diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33f85337a40d19520b36117a57720916ddbd3288..ccd1cedc6bb1cacff5002a792f74b17838583b23 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,8 +9,25 @@ This document is user facing. Please word the changes in such a way
 that users understand how the changes affect the new version.
 -->
 
-version 3.2.0-develop
+version 4.0.0-develop
 ---------------------------
++ Added a log output for STAR.
++ Added report output to Hisat2.
++ Change MultiQC inputs. It now accepts an array of reports files. It does not
+  need access to a folder with the reports anymore. MultiQC can now be used
+  as a normal WDL task without hacks.
++ Picard: Make all outputs in `CollectMultipleMetrics` optional. This will make sure the
+  task will not fail if one of the metrics is set to false.
++ The struct `BowtieIndex` was removed, as it has become obsolete.
++ The task `ReorderGlobbedScatters` was removed, as it has become obsolete.
++ Adjusted the memory settings of many tools, especially java tools.
+  They should now more accurately represent actual memory usage (as
+  opposed to virtual memory).
++ Added `-XX:ParallelGCThreads=1` to the java options of java tasks.
++ Added `timeMinutes` input to many tasks, this indicates a maximum
+  number of minutes that the job will run. The associated runtime 
+  attribute is `time_minutes` which can be used to inform
+  a scheduler (eg. slurm) of the run time of the job.
 + Added STAR GenomeGenerate task.
 + GATK.HaplotypeCaller: Add `--dont-use-soft-clipped-bases` and 
   `--standard-min-confidence-threshold-for-calling` options. These are 
diff --git a/CPAT.wdl b/CPAT.wdl
index 098d9ca61cc84de480f0a407868541937def3650..3b542e4fcb2e88859d4723f25c4659f92eb277cb 100644
--- a/CPAT.wdl
+++ b/CPAT.wdl
@@ -31,6 +31,7 @@ task CPAT {
         # CPAT should not index the reference genome.
         Array[String]? startCodons
         Array[String]? stopCodons
+        Int timeMinutes = 10 + ceil(size(gene, "G") * 30)
         String dockerImage = "biocontainers/cpat:v1.2.4_cv1"
     }
 
@@ -55,6 +56,7 @@ task CPAT {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
@@ -67,6 +69,7 @@ task CPAT {
                                category: "advanced"}
         startCodons: {description: "Equivalent to CPAT's `--start` option.", category: "advanced"}
         stopCodons: {description: "Equivalent to CPAT's `--stop` option.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/bcftools.wdl b/bcftools.wdl
index 122fcdd1e4ee0a5cc468b9b1f15d884813ac5058..53165c6be2118579bc1705a11577b52e80c8591e 100644
--- a/bcftools.wdl
+++ b/bcftools.wdl
@@ -26,6 +26,8 @@ task Bcf2Vcf {
     input {
         File bcf
         String outputPath = "./bcftools/SV.vcf"
+        String memory = "2G"
+        Int timeMinutes = 1 + ceil(size(bcf, "G"))
         String dockerImage = "quay.io/biocontainers/bcftools:1.9--ha228f0b_3"
     }
 
@@ -40,12 +42,16 @@ task Bcf2Vcf {
     }
 
     runtime {
+        memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
         bcf: {description: "The generated BCF from an SV caller", category: "required"}
         outputPath: {description: "The location the output VCF file should be written.", category: "common"}
+        memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }
diff --git a/bedtools.wdl b/bedtools.wdl
index 4f39e2a8907b3b8a713373a562e466905f727587..c228d6c6fb838f04f03a55f6729a8b8e08ceca9e 100644
--- a/bedtools.wdl
+++ b/bedtools.wdl
@@ -24,8 +24,10 @@ task Complement {
     input {
         File faidx
         File inputBed
-        String dockerImage = "quay.io/biocontainers/bedtools:2.23.0--hdbcaa40_3"
         String outputBed = basename(inputBed, "\.bed") + ".complement.bed"
+        String memory = "~{512 + ceil(size([inputBed, faidx], "M"))}M"
+        Int timeMinutes = 1 + ceil(size([inputBed, faidx], "G"))
+        String dockerImage = "quay.io/biocontainers/bedtools:2.23.0--hdbcaa40_3"
     }
 
     # Use a fasta index file to get the genome sizes. And convert that to the
@@ -44,20 +46,19 @@ task Complement {
     }
 
     runtime {
+        memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
-        faidx: {description: "The fasta index (.fai) file from which to extract the genome sizes",
-                category: "required"}
-        inputBed: {description: "The inputBed to complement",
-                category: "required"}
-        outputBed: {description: "The path to write the output to",
-                     category: "advanced"}
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        faidx: {description: "The fasta index (.fai) file from which to extract the genome sizes.", category: "required"}
+        inputBed: {description: "The inputBed to complement.", category: "required"}
+        outputBed: {description: "The path to write the output to.", category: "advanced"}
+        memory: {description: "The amount of memory needed for the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
 
@@ -65,6 +66,8 @@ task Merge {
     input {
         File inputBed
         String outputBed = "merged.bed"
+        String memory = "~{512 + ceil(size(inputBed, "M"))}M"
+        Int timeMinutes = 1 + ceil(size(inputBed, "G"))
         String dockerImage = "quay.io/biocontainers/bedtools:2.23.0--hdbcaa40_3"
     }
 
@@ -77,18 +80,18 @@ task Merge {
     }
 
     runtime {
+        memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
-        inputBed: {description: "The bed to merge",
-                   category: "required"}
-        outputBed: {description: "The path to write the output to",
-                    category: "advanced"}
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        inputBed: {description: "The bed to merge.", category: "required"}
+        outputBed: {description: "The path to write the output to.", category: "advanced"}
+        memory: {description: "The amount of memory needed for the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
 
@@ -97,6 +100,8 @@ task MergeBedFiles {
     input {
         Array[File]+ bedFiles
         String outputBed = "merged.bed"
+        String memory = "~{512 + ceil(size(bedFiles, "M"))}M"
+        Int timeMinutes = 1 + ceil(size(bedFiles, "G"))
         String dockerImage = "quay.io/biocontainers/bedtools:2.23.0--hdbcaa40_3"
     }
 
@@ -111,17 +116,17 @@ task MergeBedFiles {
     }
 
     runtime {
+        memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
     parameter_meta {
-        bedFiles: {description: "The bed files to merge",
-                category: "required"}
-        outputBed: {description: "The path to write the output to",
-                     category: "advanced"}
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        bedFiles: {description: "The bed files to merge.", category: "required"}
+        outputBed: {description: "The path to write the output to.", category: "advanced"}
+        memory: {description: "The amount of memory needed for the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
 
@@ -172,6 +177,8 @@ task Intersect {
         # Giving a faidx file will set the sorted option.
         File? faidx
         String outputBed = "intersect.bed"
+        String memory = "~{512 + ceil(size([regionsA, regionsB], "M"))}M"
+        Int timeMinutes = 1 + ceil(size([regionsA, regionsB], "G"))
         String dockerImage = "quay.io/biocontainers/bedtools:2.23.0--hdbcaa40_3"
     }
     Boolean sorted = defined(faidx)
@@ -192,21 +199,20 @@ task Intersect {
     }
 
     runtime {
+        memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
         faidx: {description: "The fasta index (.fai) file that is used to create the genome file required for sorted output. Implies sorted option.",
                 category: "common"}
-        regionsA: {description: "Region file a to intersect",
-                   category: "required"}
-        regionsB: {description: "Region file b to intersect",
-                   category: "required"}
-        outputBed: {description: "The path to write the output to",
-                    category: "advanced"}
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        regionsA: {description: "Region file a to intersect", category: "required"}
+        regionsB: {description: "Region file b to intersect", category: "required"}
+        outputBed: {description: "The path to write the output to", category: "advanced"}
+        memory: {description: "The amount of memory needed for the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
diff --git a/biopet/bamstats.wdl b/biopet/bamstats.wdl
index 7def9aec34b8d7adc50946922b86462739da5372..d71355d3a80dda92947992569b5d599944d3dc68 100644
--- a/biopet/bamstats.wdl
+++ b/biopet/bamstats.wdl
@@ -34,7 +34,7 @@ task Generate {
         String outputDir
         Reference? reference
 
-        String memory = "16G"
+        String memory = "9G"
         String javaXmx = "8G"
     }
 
diff --git a/biopet/biopet.wdl b/biopet/biopet.wdl
index ec64fb4b4df2475c112e74e5c20e3401a1cecbce..cc8e1bc6382bb452c947403c0815804a1fcb3ede 100644
--- a/biopet/biopet.wdl
+++ b/biopet/biopet.wdl
@@ -31,7 +31,7 @@ task BaseCounter {
         String outputDir
         String prefix
 
-        String memory = "14G"
+        String memory = "5G"
         String javaXmx = "4G"
     }
 
@@ -104,9 +104,10 @@ task ExtractAdaptersFastqc {
         Float? adapterCutoff
         Boolean? outputAsFasta
 
-        String memory = "40G" # This is ridiculous, but needed due to vmem monitoring on SGE.
+        String memory = "9G"
         String javaXmx = "8G"
         String dockerImage = "quay.io/biocontainers/biopet-extractadaptersfastqc:0.2--1"
+        Int timeMinutes = 5
     }
 
     command {
@@ -133,6 +134,7 @@ task ExtractAdaptersFastqc {
     runtime {
         memory: memory
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 }
 
@@ -143,7 +145,7 @@ task FastqSplitter {
         Array[String]+ outputPaths
         File? toolJar
 
-        String memory = "12G"
+        String memory = "5G"
         String javaXmx = "4G"
         String dockerImage = "quay.io/biocontainers/biopet-fastqsplitter:0.1--2"
     }
@@ -175,7 +177,7 @@ task FastqSync {
         String out2path
         File? toolJar
 
-        String memory = "10G"
+        String memory = "5G"
         String javaXmx = "4G"
     }
 
@@ -208,52 +210,6 @@ task FastqSync {
     }
 }
 
-task ReorderGlobbedScatters {
-    input {
-        Array[File]+ scatters
-
-        # Should not be changed from the main pipeline. As it should not influence results.
-        # The 3.7-slim container is 143 mb on the filesystem. 3.7 is 927 mb.
-        # The slim container is sufficient for this small task.
-        String dockerImage = "python:3.7-slim"
-    }
-
-    command <<<
-       set -e
-       # Copy all the scatter files to the CWD so the output matches paths in
-       # the cwd.
-       for file in ~{sep=" " scatters}
-          do cp $file .
-       done
-       python << CODE
-       from os.path import basename
-       scatters = ['~{sep="','" scatters}']
-       splitext = [basename(x).split(".") for x in scatters]
-       splitnum = [x.split("-") + [y] for x,y in splitext]
-       ordered = sorted(splitnum, key=lambda x: int(x[1]))
-       merged = ["{}-{}.{}".format(x[0],x[1],x[2]) for x in ordered]
-       for x in merged:
-           print(x)
-       CODE
-    >>>
-
-    output {
-        Array[File] reorderedScatters = read_lines(stdout())
-    }
-
-    runtime {
-        docker: dockerImage
-        # 4 gigs of memory to be able to build the docker image in singularity
-        memory: "4G"
-    }
-
-    parameter_meta {
-        scatters: {description: "The files which should be ordered.", category: "required"}
-        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-                      category: "advanced"}
-    }
-}
-
 task ScatterRegions {
     input {
         File referenceFasta
@@ -264,8 +220,9 @@ task ScatterRegions {
         File? bamFile
         File? bamIndex
 
-        String memory = "24G"
-        String javaXmx = "8G"
+        String memory = "1G"
+        String javaXmx = "500M"
+        Int timeMinutes = 10
         String dockerImage = "quay.io/biocontainers/biopet-scatterregions:0.2--0"
     }
 
@@ -277,7 +234,7 @@ task ScatterRegions {
     command <<<
         set -e -o pipefail
         mkdir -p ~{outputDirPath}
-        biopet-scatterregions -Xmx~{javaXmx} \
+        biopet-scatterregions -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
           -R ~{referenceFasta} \
           -o ~{outputDirPath} \
           ~{"-s " + scatterSize} \
@@ -306,6 +263,7 @@ task ScatterRegions {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -322,6 +280,7 @@ task ScatterRegions {
         bamIndex: {description: "The index for the bamfile given through bamFile.", category: "advanced"}
 
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
@@ -335,7 +294,7 @@ task ValidateAnnotation {
         File? gtfFile
         Reference reference
 
-        String memory = "9G"
+        String memory = "4G"
         String javaXmx = "3G"
         String dockerImage = "quay.io/biocontainers/biopet-validateannotation:0.1--0"
     }
@@ -361,7 +320,7 @@ task ValidateFastq {
     input {
         File read1
         File? read2
-        String memory = "9G"
+        String memory = "4G"
         String javaXmx = "3G"
         String dockerImage = "quay.io/biocontainers/biopet-validatefastq:0.1.1--1"
     }
@@ -386,7 +345,7 @@ task ValidateVcf {
     input {
         IndexedVcfFile vcf
         Reference reference
-        String memory = "9G"
+        String memory = "4G"
         String javaXmx = "3G"
         String dockerImage = "quay.io/biocontainers/biopet-validatevcf:0.1--0"
     }
@@ -430,7 +389,7 @@ task VcfStats {
         Array[String]+? sparkConfigValues
 
         String dockerImage = "quay.io/biocontainers/biopet-vcfstats:1.2--0"
-        String memory = "12G"
+        String memory = "5G"
         String javaXmx = "4G"
     }
 
diff --git a/biopet/sampleconfig.wdl b/biopet/sampleconfig.wdl
index 0fbd466a0ec1ee219f4785774c2231338c905d47..2b36952bdfe0ca9673c6d62478d0efab0c0f444c 100644
--- a/biopet/sampleconfig.wdl
+++ b/biopet/sampleconfig.wdl
@@ -34,7 +34,7 @@ task SampleConfig {
         String? jsonOutputPath
         String? tsvOutputPath
 
-        String memory = "8G"
+        String memory = "17G"
         String javaXmx = "16G"
     }
 
@@ -74,7 +74,7 @@ task SampleConfigCromwellArrays {
         Array[File]+ inputFiles
         String outputPath
 
-        String memory = "8G"
+        String memory = "5G"
         String javaXmx = "4G"
     }
 
@@ -110,7 +110,7 @@ task CaseControl {
         String outputPath
         String controlTag = "control"
 
-        String memory = "8G"
+        String memory = "5G"
         String javaXmx = "4G"
     }
 
diff --git a/biopet/seqstat.wdl b/biopet/seqstat.wdl
index 6694a75996ceb14cf8bc6b7671fe2a839ef8e8f6..e3a55ec3e7d50f219ef980fde482263a3d3f6670 100644
--- a/biopet/seqstat.wdl
+++ b/biopet/seqstat.wdl
@@ -32,7 +32,7 @@ task Generate {
         String library
         String readgroup
 
-        String memory = "10G"
+        String memory = "5G"
         String javaXmx = "4G"
     }
 
diff --git a/biowdl.wdl b/biowdl.wdl
index 7aa68b271b73ac6c098fe1b0deffa6a06178b4a3..838755d911b42a729774c227d8521634c37c7b86 100644
--- a/biowdl.wdl
+++ b/biowdl.wdl
@@ -31,6 +31,8 @@ task InputConverter {
         Boolean skipFileCheck=true
         Boolean checkFileMd5sums=false
         Boolean old=false
+
+        Int timeMinutes = 1
         String dockerImage = "quay.io/biocontainers/biowdl-input-converter:0.2.1--py_0"
     }
 
@@ -50,6 +52,8 @@ task InputConverter {
     }
 
     runtime {
+        memory: "128M"
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -62,6 +66,7 @@ task InputConverter {
         checkFileMd5sums: {description: "Whether or not the MD5 sums of the files mentioned in the samplesheet should be checked.",
                            category: "advanced"}
         old: {description: "Whether or not the old samplesheet format should be used.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/bowtie.wdl b/bowtie.wdl
index 18fd6146adb6ea1b606f9d7b3bec6753d2c8fca4..b3f3ceaeadcc165cb2feec9d4e734f31e32c437c 100644
--- a/bowtie.wdl
+++ b/bowtie.wdl
@@ -37,7 +37,8 @@ task Bowtie {
         String? samRG
 
         Int threads = 1
-        String memory = "16G"
+        Int timeMinutes = 1 + ceil(size(flatten([readsUpstream, readsDownstream]), "G") * 300 / threads)
+        String memory = "~{5 + ceil(size(indexFiles, "G"))}G"
         String picardXmx = "4G"
         # Image contains bowtie=1.2.2 and picard=2.9.2
         String dockerImage = "quay.io/biocontainers/mulled-v2-bfe71839265127576d3cd749c056e7b168308d56:1d8bec77b352cdcf3e9ff3d20af238b33ed96eae-0"
@@ -78,6 +79,7 @@ task Bowtie {
     runtime {
         cpu: threads
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -98,12 +100,8 @@ task Bowtie {
                   category: "advanced"}
         threads: {description: "The number of threads to use.", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
 }
-
-struct BowtieIndex {
-    File fasta
-    Array[File] indexFiles
-}
\ No newline at end of file
diff --git a/bwa.wdl b/bwa.wdl
index fec2b09f0b17279810759baabce7c5189833ee2d..3dd7883bd9920d83edd3d9250e9fbad29e496f51 100644
--- a/bwa.wdl
+++ b/bwa.wdl
@@ -29,8 +29,9 @@ task Mem {
         String? readgroup
 
         Int threads = 4
-        String memory = "32G"
+        String memory = "~{5 + ceil(size(bwaIndex.indexFiles, "G"))}G"
         String picardXmx = "4G"
+        Int timeMinutes = 1 + ceil(size([read1, read2], "G") * 200 / threads)
         # A mulled container is needed to have both picard and bwa in one container.
         # This container contains: picard (2.18.7), bwa (0.7.17-r1188)
         String dockerImage = "quay.io/biocontainers/mulled-v2-002f51ea92721407ef440b921fb5940f424be842:43ec6124f9f4f875515f9548733b8b4e5fed9aa6-0"
@@ -45,7 +46,7 @@ task Mem {
         ~{bwaIndex.fastaFile} \
         ~{read1} \
         ~{read2} \
-        | picard -Xmx~{picardXmx} SortSam \
+        | picard -Xmx~{picardXmx} -XX:ParallelGCThreads=1 SortSam \
         INPUT=/dev/stdin \
         OUTPUT=~{outputPath} \
         SORT_ORDER=coordinate \
@@ -60,6 +61,7 @@ task Mem {
     runtime {
         cpu: threads
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -74,6 +76,7 @@ task Mem {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         picardXmx: {description: "The maximum memory available to picard SortSam. Should be lower than `memory` to accommodate JVM overhead and BWA mem's memory usage.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -96,7 +99,8 @@ task Kit {
         # GATK/Picard default is level 2.
         String sortMemoryPerThread = "4G"
         Int compressionLevel = 1
-        String memory = "32G"
+        String memory = "20G"
+        Int timeMinutes = 1 + ceil(size([read1, read2], "G") * 220 / threads)
         String dockerImage = "biocontainers/bwakit:v0.7.15_cv1"
     }
 
@@ -130,6 +134,7 @@ task Kit {
     runtime {
         cpu: threads + 1  # One thread for bwa-postalt + samtools.
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -146,6 +151,7 @@ task Kit {
         sortMemoryPerThread: {description: "The amount of memory for each sorting thread.", category: "advanced"}
         compressionLevel: {description: "The compression level of the output BAM.", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
 
diff --git a/ccs.wdl b/ccs.wdl
index 3a8f887947faab7bc3ee898cf06fcd6ca28586d8..1762ac75decc526370ba83d46db018a9168c5da0 100644
--- a/ccs.wdl
+++ b/ccs.wdl
@@ -33,6 +33,7 @@ task CCS {
         
         Int cores = 2
         String memory = "2G"
+        Int timeMinutes = 1440
         String dockerImage = "quay.io/biocontainers/pbccs:4.2.0--0"
     }
 
@@ -63,6 +64,7 @@ task CCS {
     runtime {
         cpu: cores
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -78,6 +80,7 @@ task CCS {
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         cores: {description: "The number of cores to be used.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
diff --git a/centrifuge.wdl b/centrifuge.wdl
index 1fbc7be11726db716b2b9edd6b9b7b5528c74ac3..f2b26043de9becf264f1d136e2d5a39a1429c723 100644
--- a/centrifuge.wdl
+++ b/centrifuge.wdl
@@ -37,6 +37,7 @@ task Build {
 
         Int threads = 5
         String memory = "20G"
+        Int timeMinutes = 2880
         String dockerImage = "quay.io/biocontainers/centrifuge:1.0.4_beta--he513fc3_5"
     }
 
@@ -64,6 +65,7 @@ task Build {
     runtime {
         cpu: threads
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -82,6 +84,7 @@ task Build {
         sizeTable: {description: "List of taxonomic IDs and lengths of the sequences belonging to the same taxonomic IDs.", category: "common"}
         threads: {description: "The number of threads to be used.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -184,6 +187,7 @@ task Inspect {
         Int? across
 
         String memory = "4G"
+        Int timeMinutes = 1
         String dockerImage = "quay.io/biocontainers/centrifuge:1.0.4_beta--he513fc3_5"
     }
 
@@ -210,6 +214,7 @@ task Inspect {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -220,6 +225,7 @@ task Inspect {
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         across: {description: "When printing FASTA output, output a newline character every <int> bases.", category: "common"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -307,6 +313,7 @@ task Kreport {
         Int? minimumLength
 
         String memory = "4G"
+        Int timeMinutes = 10
         String dockerImage = "quay.io/biocontainers/centrifuge:1.0.4_beta--he513fc3_5"
     }
 
@@ -335,6 +342,7 @@ task Kreport {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -349,6 +357,7 @@ task Kreport {
         minimumScore: {description: "Require a minimum score for reads to be counted.", category: "advanced"}
         minimumLength: {description: "Require a minimum alignment length to the read.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -362,6 +371,7 @@ task KTimportTaxonomy {
         String outputPrefix
 
         String memory = "4G"
+        Int timeMinutes = 1
         String dockerImage = "biocontainers/krona:v2.7.1_cv1"
     }
 
@@ -379,6 +389,7 @@ task KTimportTaxonomy {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -387,6 +398,7 @@ task KTimportTaxonomy {
         inputFile: {description: "File with Centrifuge classification results.", category: "required"}
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
diff --git a/chunked-scatter.wdl b/chunked-scatter.wdl
index 619292d9f647bd76f30e29b07a8c08b84f4bf707..1b81687abda2b37851b8062eed02eb0420b458f0 100644
--- a/chunked-scatter.wdl
+++ b/chunked-scatter.wdl
@@ -28,6 +28,7 @@ task ChunkedScatter {
         Int? overlap
         Int? minimumBasesPerFile
 
+        Int timeMinutes = 2
         String dockerImage = "quay.io/biocontainers/chunked-scatter:0.1.0--py_0"
     }
 
@@ -48,6 +49,7 @@ task ChunkedScatter {
 
     runtime {
         memory: "4G"
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
diff --git a/clever.wdl b/clever.wdl
index e1dcf5a66401a21414cdd84c6087cee5933efebc..3a6515f721ff642ce3d91f7f8189db0b4542e2d7 100644
--- a/clever.wdl
+++ b/clever.wdl
@@ -37,6 +37,7 @@ task Mateclever {
 
         Int threads = 10
         String memory = "15G"
+        Int timeMinutes = 600
         String dockerImage = "quay.io/biocontainers/clever-toolkit:2.4--py36hcfe0e84_6"
     }
 
@@ -63,6 +64,7 @@ task Mateclever {
     runtime {
         cpu: threads
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -78,6 +80,7 @@ task Mateclever {
         outputPath: {description: "The location the output VCF file should be written.", category: "common"}
         threads: {description: "The the number of threads required to run a program", category: "advanced"}
         memory: {description: "The memory required to run the programs", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }
@@ -90,7 +93,8 @@ task Prediction {
         String outputPath = "./clever"
 
         Int threads = 10
-        String memory = "15G"
+        String memory = "55G"
+        Int timeMinutes = 480
         String dockerImage = "quay.io/biocontainers/clever-toolkit:2.4--py36hcfe0e84_6"
     }
 
@@ -114,6 +118,7 @@ task Prediction {
     runtime {
         cpu: threads
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -125,6 +130,7 @@ task Prediction {
         outputPath: {description: "The location the output VCF file should be written.", category: "common"}
         threads: {description: "The the number of threads required to run a program", category: "advanced"}
         memory: {description: "The memory required to run the programs", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
diff --git a/collect-columns.wdl b/collect-columns.wdl
index 8b1fa387d7bf277fc4832344beba48c2e5a5d667..e4e3a948dc8665dd34837a43e43a046fb40e7037 100644
--- a/collect-columns.wdl
+++ b/collect-columns.wdl
@@ -33,6 +33,8 @@ task CollectColumns {
         File? referenceGtf
         String? featureAttribute
 
+        Int memoryGb = 4 + ceil(0.5 * length(inputTables))
+        Int timeMinutes = 10
         String dockerImage = "quay.io/biocontainers/collect-columns:0.2.0--py_1"
     }
 
@@ -56,34 +58,25 @@ task CollectColumns {
         File outputTable = outputPath
     }
 
-    Int memoryGb = 4 + ceil(0.5 * length(inputTables))
-
     runtime {
         memory: "~{memoryGb}G"
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
-        inputTables: {description: "The tables from which columns should be taken.",
-                      category: "required"}
-        outputPath: {description: "The path to which the output should be written.",
-                     category: "required"}
-        featureColumn: {description: "Equivalent to the -f option of collect-columns.",
-                        category: "advanced"}
-        valueColumn: {description: "Equivalent to the -c option of collect-columns.",
-                      category: "advanced"}
-        separator: {description: "Equivalent to the -s option of collect-columns.",
-                    category: "advanced"}
-        sampleNames: {description: "Equivalent to the -n option of collect-columns.",
-                      category: "advanced"}
-        header: {description: "Equivalent to the -H flag of collect-columns.",
-                 category: "advanced"}
-        additionalAttributes: {description: "Equivalent to the -a option of collect-columns.",
-                               category: "advanced"}
-        referenceGtf: {description: "Equivalent to the -g option of collect-columns.",
-                       category: "advanced"}
-        featureAttribute: {description: "Equivalent to the -F option of collect-columns.",
-                           category: "advanced"}
+        inputTables: {description: "The tables from which columns should be taken.", category: "required"}
+        outputPath: {description: "The path to which the output should be written.", category: "required"}
+        featureColumn: {description: "Equivalent to the -f option of collect-columns.", category: "advanced"}
+        valueColumn: {description: "Equivalent to the -c option of collect-columns.", category: "advanced"}
+        separator: {description: "Equivalent to the -s option of collect-columns.", category: "advanced"}
+        sampleNames: {description: "Equivalent to the -n option of collect-columns.", category: "advanced"}
+        header: {description: "Equivalent to the -H flag of collect-columns.", category: "advanced"}
+        additionalAttributes: {description: "Equivalent to the -a option of collect-columns.", category: "advanced"}
+        referenceGtf: {description: "Equivalent to the -g option of collect-columns.", category: "advanced"}
+        featureAttribute: {description: "Equivalent to the -F option of collect-columns.", category: "advanced"}
+        memoryGb: {description: "The maximum amount of memory the job will need in GB", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/common.wdl b/common.wdl
index ef86abcc2c62b564fc23aeae227a2c95b4bfe652..f83255230874d77350b2d662e643f5e5e1f75aa2 100644
--- a/common.wdl
+++ b/common.wdl
@@ -179,10 +179,10 @@ task StringArrayMd5 {
 }
 
 task TextToFile {
-
     input {
         String text
         String outputFile = "out.txt"
+        Int timeMinutes = 1
         String dockerImage = "debian@sha256:f05c05a218b7a4a5fe979045b1c8e2a9ec3524e5611ebfdd0ef5b8040f9008fa"
     }
 
@@ -197,11 +197,13 @@ task TextToFile {
     parameter_meta {
         text: {description: "The text to print", category: "required"}
         outputFile: {description: "The name of the output file", category: "common"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
     runtime {
         memory: "1G"
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 }
@@ -210,6 +212,9 @@ task YamlToJson {
     input {
         File yaml
         String outputJson = basename(yaml, "\.ya?ml$") + ".json"
+
+        Int timeMinutes = 1
+        String  memory = "128M"
         # biowdl-input-converter has python and pyyaml.
         String dockerImage = "quay.io/biocontainers/biowdl-input-converter:0.2.1--py_0"
     }
@@ -230,12 +235,16 @@ task YamlToJson {
     }
 
     runtime {
+        memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
         yaml: {description: "The YAML file to convert.", category: "required"}
         outputJson: {description: "The location the output JSON file should be written to.", category: "advanced"}
+        memory: {description: "The maximum aount of memroy the job will need.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/cutadapt.wdl b/cutadapt.wdl
index d04865b618f61a4891bf753b64d1ad3f8bc11849..ad32ff21aff4958f9955628753a7b68468a855cd 100644
--- a/cutadapt.wdl
+++ b/cutadapt.wdl
@@ -79,7 +79,8 @@ task Cutadapt {
         # Hence we use compression level 1 here.
         Int compressionLevel = 1  # This only affects outputs with the .gz suffix.
         Int cores = 4
-        String memory = "4G"
+        String memory = "~{300 + 100 * cores}M"
+        Int timeMinutes = 1 + ceil(size([read1, read2], "G")  * 12.0 / cores)
         String dockerImage = "quay.io/biocontainers/cutadapt:2.8--py37h516909a_0"
     }
 
@@ -167,231 +168,75 @@ task Cutadapt {
     runtime {
         cpu: cores
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
-        read1: {
-            description: "The first or single end fastq file to be run through cutadapt.",
-            category: "required"
-        }
-        read2: {
-            description: "An optional second end fastq file to be run through cutadapt.",
-            category: "common"
-        }
-        read1output: {
-            description: "The name of the resulting first or single end fastq file.",
-            category: "common"
-        }
-        read2output: {
-            description: "The name of the resulting second end fastq file.",
-            category: "common"
-        }
-        adapter: {
-            description: "A list of 3' ligated adapter sequences to be cut from the given first or single end fastq file.",
-            category: "common"
-        }
-        front: {
-            description: "A list of 5' ligated adapter sequences to be cut from the given first or single end fastq file.",
-            category: "advanced"
-        }
-        anywhere: {
-            description: "A list of 3' or 5' ligated adapter sequences to be cut from the given first or single end fastq file.",
-            category: "advanced"
-        }
-        adapterRead2: {
-            description: "A list of 3' ligated adapter sequences to be cut from the given second end fastq file.",
-            category: "common"
-        }
-        frontRead2: {
-            description: "A list of 5' ligated adapter sequences to be cut from the given second end fastq file.",
-            category: "advanced"
-        }
-        anywhereRead2: {
-            description: "A list of 3' or 5' ligated adapter sequences to be cut from the given second end fastq file.",
-            category: "advanced"
-        }
-        interleaved: {
-            description: "Equivalent to cutadapt's --interleaved flag.",
-            category: "advanced"
-        }
-        pairFilter: {
-            description: "Equivalent to cutadapt's --pair-filter option.",
-            category: "advanced"
-        }
-        errorRate: {
-            description: "Equivalent to cutadapt's --error-rate option.",
-            category: "advanced"
-        }
-        noIndels: {
-            description: "Equivalent to cutadapt's --no-indels flag.",
-            category: "advanced"
-        }
-        times: {
-            description: "Equivalent to cutadapt's --times option.",
-            category: "advanced"
-        }
-        overlap: {
-            description: "Equivalent to cutadapt's --overlap option.",
-            category: "advanced"
-        }
-        matchReadWildcards: {
-            description: "Equivalent to cutadapt's --match-read-wildcards flag.",
-            category: "advanced"
-        }
-        noMatchAdapterWildcards: {
-            description: "Equivalent to cutadapt's --no-match-adapter-wildcards flag.",
-            category: "advanced"
-        }
-        noTrim: {
-            description: "Equivalent to cutadapt's --no-trim flag.",
-            category: "advanced"
-        }
-        maskAdapter: {
-            description: "Equivalent to cutadapt's --mask-adapter flag.",
-            category: "advanced"
-        }
-        cut: {
-            description: "Equivalent to cutadapt's --cut option.",
-            category: "advanced"
-        }
-        nextseqTrim: {
-            description: "Equivalent to cutadapt's --nextseq-trim option.",
-            category: "advanced"
-        }
-        qualityCutoff: {
-            description: "Equivalent to cutadapt's --quality-cutoff option.",
-            category: "advanced"
-        }
-        qualityBase: {
-            description: "Equivalent to cutadapt's --quality-base option.",
-            category: "advanced"
-        }
-        length: {
-            description: "Equivalent to cutadapt's --length option.",
-            category: "advanced"
-        }
-        trimN: {
-            description: "Equivalent to cutadapt's --trim-n flag.",
-            category: "advanced"
-        }
-        lengthTag: {
-            description: "Equivalent to cutadapt's --length-tag option.",
-            category: "advanced"
-        }
-        stripSuffix: {
-            description: "Equivalent to cutadapt's --strip-suffix option.",
-            category: "advanced"
-        }
-        prefix: {
-            description: "Equivalent to cutadapt's --prefix option.",
-            category: "advanced"
-        }
-        suffix: {
-            description: "Equivalent to cutadapt's --suffix option.",
-            category: "advanced"
-        }
-        minimumLength: {
-            description: "Equivalent to cutadapt's --minimum-length option.",
-            category: "advanced"
-        }
-        maximumLength: {
-            description: "Equivalent to cutadapt's --maximum-length option.",
-            category: "advanced"
-        }
-        maxN: {
-            description: "Equivalent to cutadapt's --max-n option.",
-            category: "advanced"
-        }
-        discardTrimmed: {
-            description: "Equivalent to cutadapt's --quality-cutoff option.",
-            category: "advanced"
-        }
-        discardUntrimmed: {
-            description: "Equivalent to cutadapt's --discard-untrimmed option.",
-            category: "advanced"
-        }
-        infoFilePath: {
-            description: "Equivalent to cutadapt's --info-file option.",
-            category: "advanced"
-        }
-        restFilePath: {
-            description: "Equivalent to cutadapt's --rest-file option.",
-            category: "advanced"
-        }
-        wildcardFilePath: {
-            description: "Equivalent to cutadapt's --wildcard-file option.",
-            category: "advanced"
-        }
-        tooShortOutputPath: {
-            description: "Equivalent to cutadapt's --too-short-output option.",
-            category: "advanced"
-        }
-        tooLongOutputPath: {
-            description: "Equivalent to cutadapt's --too-long-output option.",
-            category: "advanced"
-        }
-        untrimmedOutputPath: {
-            description: "Equivalent to cutadapt's --untrimmed-output option.",
-            category: "advanced"
-        }
-        tooShortPairedOutputPath: {
-            description: "Equivalent to cutadapt's --too-short-paired-output option.",
-            category: "advanced"
-        }
-        tooLongPairedOutputPath: {
-            description: "Equivalent to cutadapt's --too-long-paired-output option.",
-            category: "advanced"
-        }
-        untrimmedPairedOutputPath: {
-            description: "Equivalent to cutadapt's --untrimmed-paired-output option.",
-            category: "advanced"
-        }
-        colorspace: {
-            description: "Equivalent to cutadapt's --colorspace flag.",
-            category: "advanced"
-        }
-        doubleEncode: {
-            description: "Equivalent to cutadapt's --double-encode flag.",
-            category: "advanced"
-        }
-        stripF3: {
-            description: "Equivalent to cutadapt's --strip-f3 flag.",
-            category: "advanced"
-        }
-        maq: {
-            description: "Equivalent to cutadapt's --maq flag.",
-            category: "advanced"
-        }
-        bwa: {
-            description: "Equivalent to cutadapt's --bwa flag.",
-            category: "advanced"
-        }
-        zeroCap: {
-            description: "Equivalent to cutadapt's --zero-cap flag.",
-            category: "advanced"
-        }
-        noZeroCap: {
-            description: "Equivalent to cutadapt's --no-zero-cap flag.",
-            category: "advanced"
-        }
-        reportPath: {
-            description: "The name of the file to write cutadapts's stdout to, this contains some metrics.",
-            category: "common"
-        }
-        compressionLevel: {description: "The compression level if gzipped output is used.",
-                           category: "advanced"}
-        cores: {
-            description: "The number of cores to use.",
-            category: "advanced"
-        }
-        memory: {
-            description: "The amount of memory this job will use.",
-            category: "advanced"
-        }
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        read1: {description: "The first or single end fastq file to be run through cutadapt.", category: "required"}
+        read2: {description: "An optional second end fastq file to be run through cutadapt.", category: "common"}
+        read1output: {description: "The name of the resulting first or single end fastq file.", category: "common"}
+        read2output: {description: "The name of the resulting second end fastq file.", category: "common"}
+        adapter: {description: "A list of 3' ligated adapter sequences to be cut from the given first or single end fastq file.",
+                  category: "common"}
+        front: {description: "A list of 5' ligated adapter sequences to be cut from the given first or single end fastq file.",
+                category: "advanced"}
+        anywhere: {description: "A list of 3' or 5' ligated adapter sequences to be cut from the given first or single end fastq file.",
+                   category: "advanced"}
+        adapterRead2: {description: "A list of 3' ligated adapter sequences to be cut from the given second end fastq file.",
+                       category: "common"}
+        frontRead2: {description: "A list of 5' ligated adapter sequences to be cut from the given second end fastq file.",
+                     category: "advanced"}
+        anywhereRead2: {description: "A list of 3' or 5' ligated adapter sequences to be cut from the given second end fastq file.",
+                        category: "advanced"}
+        interleaved: {description: "Equivalent to cutadapt's --interleaved flag.", category: "advanced"}
+        pairFilter: {description: "Equivalent to cutadapt's --pair-filter option.", category: "advanced"}
+        errorRate: {description: "Equivalent to cutadapt's --error-rate option.", category: "advanced"}
+        noIndels: {description: "Equivalent to cutadapt's --no-indels flag.", category: "advanced"}
+        times: {description: "Equivalent to cutadapt's --times option.", category: "advanced"}
+        overlap: {description: "Equivalent to cutadapt's --overlap option.", category: "advanced"}
+        matchReadWildcards: {description: "Equivalent to cutadapt's --match-read-wildcards flag.", category: "advanced"}
+        noMatchAdapterWildcards: {description: "Equivalent to cutadapt's --no-match-adapter-wildcards flag.", category: "advanced"}
+        noTrim: {description: "Equivalent to cutadapt's --no-trim flag.", category: "advanced"}
+        maskAdapter: {description: "Equivalent to cutadapt's --mask-adapter flag.", category: "advanced"}
+        cut: {description: "Equivalent to cutadapt's --cut option.", category: "advanced"}
+        nextseqTrim: {description: "Equivalent to cutadapt's --nextseq-trim option.", category: "advanced"}
+        qualityCutoff: {description: "Equivalent to cutadapt's --quality-cutoff option.", category: "advanced"}
+        qualityBase: {description: "Equivalent to cutadapt's --quality-base option.", category: "advanced"}
+        length: {description: "Equivalent to cutadapt's --length option.", category: "advanced"}
+        trimN: {description: "Equivalent to cutadapt's --trim-n flag.", category: "advanced"}
+        lengthTag: {description: "Equivalent to cutadapt's --length-tag option.", category: "advanced"}
+        stripSuffix: {description: "Equivalent to cutadapt's --strip-suffix option.", category: "advanced"}
+        prefix: {description: "Equivalent to cutadapt's --prefix option.", category: "advanced"}
+        suffix: {description: "Equivalent to cutadapt's --suffix option.", category: "advanced"}
+        minimumLength: {description: "Equivalent to cutadapt's --minimum-length option.", category: "advanced"}
+        maximumLength: {description: "Equivalent to cutadapt's --maximum-length option.", category: "advanced"}
+        maxN: {description: "Equivalent to cutadapt's --max-n option.", category: "advanced"}
+        discardTrimmed: {description: "Equivalent to cutadapt's --quality-cutoff option.", category: "advanced"}
+        discardUntrimmed: {description: "Equivalent to cutadapt's --discard-untrimmed option.", category: "advanced"}
+        infoFilePath: {description: "Equivalent to cutadapt's --info-file option.", category: "advanced"}
+        restFilePath: {description: "Equivalent to cutadapt's --rest-file option.", category: "advanced"}
+        wildcardFilePath: {description: "Equivalent to cutadapt's --wildcard-file option.", category: "advanced"}
+        tooShortOutputPath: {description: "Equivalent to cutadapt's --too-short-output option.", category: "advanced"}
+        tooLongOutputPath: {description: "Equivalent to cutadapt's --too-long-output option.", category: "advanced"}
+        untrimmedOutputPath: {description: "Equivalent to cutadapt's --untrimmed-output option.", category: "advanced"}
+        tooShortPairedOutputPath: {description: "Equivalent to cutadapt's --too-short-paired-output option.", category: "advanced"}
+        tooLongPairedOutputPath: {description: "Equivalent to cutadapt's --too-long-paired-output option.", category: "advanced"}
+        untrimmedPairedOutputPath: {description: "Equivalent to cutadapt's --untrimmed-paired-output option.", category: "advanced"}
+        colorspace: {description: "Equivalent to cutadapt's --colorspace flag.", category: "advanced"}
+        doubleEncode: {description: "Equivalent to cutadapt's --double-encode flag.", category: "advanced"}
+        stripF3: {description: "Equivalent to cutadapt's --strip-f3 flag.", category: "advanced"}
+        maq: {description: "Equivalent to cutadapt's --maq flag.", category: "advanced"}
+        bwa: {description: "Equivalent to cutadapt's --bwa flag.", category: "advanced"}
+        zeroCap: {description: "Equivalent to cutadapt's --zero-cap flag.", category: "advanced"}
+        noZeroCap: {description: "Equivalent to cutadapt's --no-zero-cap flag.", category: "advanced"}
+        reportPath: {description: "The name of the file to write cutadapts's stdout to, this contains some metrics.",
+                     category: "common"}
+        compressionLevel: {description: "The compression level if gzipped output is used.", category: "advanced"}
+        cores: {description: "The number of cores to use.", category: "advanced"}
+        memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
diff --git a/delly.wdl b/delly.wdl
index ad8f18d9579d35ab161499cfd70cf28742fa1ce6..efa1bf60d7be4483f00607c66250b8247d49b7e0 100644
--- a/delly.wdl
+++ b/delly.wdl
@@ -31,6 +31,7 @@ task CallSV {
         String outputPath = "./delly/delly.vcf"
 
         String memory = "15G"
+        Int timeMinutes = 300
         String dockerImage = "quay.io/biocontainers/delly:0.8.1--h4037b6b_1"
     }
 
@@ -49,6 +50,7 @@ task CallSV {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -60,6 +62,7 @@ task CallSV {
         referenceFastaFai: {description: "Fasta index (.fai) file of the reference", category: "required" }
         outputPath: {description: "The location the output VCF file should be written.", category: "common"}
         memory: {description: "The memory required to run the programs", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }
diff --git a/fastqc.wdl b/fastqc.wdl
index 4d10147cc8cbbc404a095be85603322452a384ee..e24b6ce44afcc62d95e752bddf88401c48e4bb6b 100644
--- a/fastqc.wdl
+++ b/fastqc.wdl
@@ -38,7 +38,9 @@ task Fastqc {
         String? dir
 
         Int threads = 1
-        String memory = "4G"
+        # Fastqc uses 250MB per thread in its wrapper.
+        String memory = "~{250 + 250 * threads}M"
+        Int timeMinutes = 1 + ceil(size(seqFile, "G")) * 4
         String dockerImage = "quay.io/biocontainers/fastqc:0.11.9--0"
         Array[File]? NoneArray
         File? NoneFile
@@ -84,6 +86,7 @@ task Fastqc {
         cpu: threads
         memory: memory
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
@@ -103,6 +106,7 @@ task Fastqc {
         dir: {description: "Equivalent to fastqc's --dir option.", category: "advanced"}
         threads: {description: "The number of cores to use.", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -116,6 +120,7 @@ task Fastqc {
 
 task GetConfiguration {
     input {
+        Int timeMinutes = 1
         String dockerImage = "quay.io/biocontainers/fastqc:0.11.7--4"
     }
 
@@ -138,13 +143,13 @@ task GetConfiguration {
 
     runtime {
         memory: "2G" # Needs more than 1 to pull the docker image
+        time_minute: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
diff --git a/gatk.wdl b/gatk.wdl
index 586c25d09edfde9cb6efa6387c445fb8b37753e9..edafc4d4cc9a4acb24bbcd5b385ab7e628cf7966 100644
--- a/gatk.wdl
+++ b/gatk.wdl
@@ -32,15 +32,16 @@ task AnnotateIntervals {
         File? segmentalDuplicationTrack
         Int featureQueryLookahead = 1000000
 
-        String memory = "10G"
+        String memory = "3G"
         String javaXmx = "2G"
+        Int timeMinutes = 5
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{annotatedIntervalsPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         AnnotateIntervals \
         -R ~{referenceFasta} \
         -L ~{intervals} \
@@ -57,6 +58,7 @@ task AnnotateIntervals {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -73,6 +75,7 @@ task AnnotateIntervals {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -90,15 +93,16 @@ task ApplyBQSR {
         File referenceFastaDict
         File referenceFastaFai
 
-        String memory = "12G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 120 # This will likely be used with intervals, as such size based estimation can't be used.
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputBamPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         ApplyBQSR \
         --create-output-bam-md5 \
         --add-output-sam-program-record \
@@ -121,6 +125,7 @@ task ApplyBQSR {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -139,6 +144,7 @@ task ApplyBQSR {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -159,15 +165,16 @@ task BaseRecalibrator {
         File referenceFastaDict
         File referenceFastaFai
 
-        String memory = "12G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 120 # This will likely be used with intervals, as such size based estimation can't be used.
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{recalibrationReportPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         BaseRecalibrator \
         -R ~{referenceFasta} \
         -I ~{inputBam} \
@@ -184,6 +191,7 @@ task BaseRecalibrator {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -205,6 +213,7 @@ task BaseRecalibrator {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -215,14 +224,15 @@ task CalculateContamination {
         File tumorPileups
         File? normalPileups
 
-        String memory = "24G"
+        String memory = "13G"
         String javaXmx = "12G"
+        Int timeMinutes = 180
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.2.0--1"
     }
 
     command {
         set -e
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         CalculateContamination \
         -I ~{tumorPileups} \
         ~{"-matched " + normalPileups} \
@@ -237,6 +247,7 @@ task CalculateContamination {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -246,6 +257,7 @@ task CalculateContamination {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -256,15 +268,16 @@ task CallCopyRatioSegments {
         String outputPrefix
         File copyRatioSegments
 
-        String memory = "21G"
-        String javaXmx = "6G"
+        String memory = "3G"
+        String javaXmx = "2G"
+        Int timeMinutes = 2
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPrefix})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         CallCopyRatioSegments \
         -I ~{copyRatioSegments} \
         -O ~{outputPrefix}.called.seg
@@ -277,6 +290,7 @@ task CallCopyRatioSegments {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -286,6 +300,7 @@ task CallCopyRatioSegments {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -301,15 +316,17 @@ task CollectAllelicCounts {
         File referenceFasta
         File referenceFastaDict
         File referenceFastaFai
-        String memory = "90G"
-        String javaXmx = "30G"
+
+        String memory = "11G"
+        String javaXmx = "10G"
+        Int timeMinutes = 120
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{allelicCountsPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         CollectAllelicCounts \
         -L ~{commonVariantSites} \
         -I ~{inputBam} \
@@ -323,6 +340,7 @@ task CollectAllelicCounts {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -338,6 +356,7 @@ task CollectAllelicCounts {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -354,15 +373,16 @@ task CollectReadCounts {
         File referenceFastaFai
         String intervalMergingRule = "OVERLAPPING_ONLY"
 
-        String memory = "35G"
+        String memory = "8G"
         String javaXmx = "7G"
+        Int timeMinutes = 1 + ceil(size(inputBam, "G") * 5)
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{countsPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         CollectReadCounts \
         -L ~{intervals} \
         -I ~{inputBam} \
@@ -378,6 +398,7 @@ task CollectReadCounts {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -393,6 +414,7 @@ task CollectReadCounts {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -408,15 +430,16 @@ task CombineGVCFs {
         File referenceFastaDict
         File referenceFastaFai
 
-        String memory = "24G"
-        String javaXmx = "12G"
+        String memory = "5G"
+        String javaXmx = "4G"
+        Int timeMinutes = 1 + ceil(size(gvcfFiles, "G") * 8)
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         CombineGVCFs \
         -R ~{referenceFasta} \
         -O ~{outputPath} \
@@ -431,6 +454,7 @@ task CombineGVCFs {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -448,6 +472,7 @@ task CombineGVCFs {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -465,8 +490,9 @@ task CombineVariants {
         Array[File]+ variantIndexes
         String outputPath
 
-        String memory = "24G"
+        String memory = "13G"
         String javaXmx = "12G"
+        Int timeMinutes = 180
         String dockerImage = "broadinstitute/gatk3:3.8-1"
     }
 
@@ -485,7 +511,7 @@ task CombineVariants {
             printf -- "-V:%s %s " "${ids[i]}" "${vars[i]}"
           done
         ')
-        java -Xmx~{javaXmx} -jar /usr/GenomeAnalysisTK.jar \
+        java -Xmx~{javaXmx} -XX:ParallelGCThreads=1 -jar /usr/GenomeAnalysisTK.jar \
         -T CombineVariants \
         -R ~{referenceFasta} \
         --genotypemergeoption ~{genotypeMergeOption} \
@@ -501,6 +527,7 @@ task CombineVariants {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -518,6 +545,7 @@ task CombineVariants {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -529,15 +557,16 @@ task CreateReadCountPanelOfNormals {
         Array[File]+ readCountsFiles
         File? annotatedIntervals
 
-        String memory = "21G"
+        String memory = "8G"
         String javaXmx = "7G"
+        Int timeMinutes = 5
         String dockerImage = "broadinstitute/gatk:4.1.4.0" # The biocontainer causes a spark related error for some reason...
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{PONpath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         CreateReadCountPanelOfNormals \
         -I ~{sep=" -I " readCountsFiles} \
         ~{"--annotated-intervals " + annotatedIntervals} \
@@ -550,6 +579,7 @@ task CreateReadCountPanelOfNormals {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -561,6 +591,7 @@ task CreateReadCountPanelOfNormals {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -573,15 +604,16 @@ task DenoiseReadCounts {
         File readCounts
         String outputPrefix
 
-        String memory = "39G"
-        String javaXmx = "13G"
+        String memory = "5G"
+        String javaXmx = "4G"
+        Int timeMinutes = 5
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPrefix})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         DenoiseReadCounts \
         -I ~{readCounts} \
         ~{"--count-panel-of-normals " + PON} \
@@ -597,6 +629,7 @@ task DenoiseReadCounts {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -609,6 +642,7 @@ task DenoiseReadCounts {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -628,15 +662,16 @@ task FilterMutectCalls {
         Int uniqueAltReadCount = 4
         File mutect2Stats
 
-        String memory = "24G"
+        String memory = "13G"
         String javaXmx = "12G"
+        Int timeMinutes = 60
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.2.0--1"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputVcf})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         FilterMutectCalls \
         -R ~{referenceFasta} \
         -V ~{unfilteredVcf} \
@@ -658,6 +693,7 @@ task FilterMutectCalls {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -677,6 +713,7 @@ task FilterMutectCalls {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -688,15 +725,16 @@ task GatherBqsrReports {
         Array[File] inputBQSRreports
         String outputReportPath
 
-        String memory = "12G"
-        String javaXmx = "4G"
+        String memory = "1G"
+        String javaXmx = "500M"
+        Int timeMinutes = 1
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputReportPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         GatherBQSRReports \
         -I ~{sep=' -I ' inputBQSRreports} \
         -O ~{outputReportPath}
@@ -708,6 +746,7 @@ task GatherBqsrReports {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -718,6 +757,7 @@ task GatherBqsrReports {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -731,15 +771,16 @@ task GenomicsDBImport {
         String genomicsDBWorkspacePath = "genomics_db"
         String genomicsDBTarFile = "genomics_db.tar.gz"
         String? tmpDir
-        String memory = "12G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 180
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{genomicsDBWorkspacePath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         GenomicsDBImport \
         -V ~{sep=" -V " gvcfFiles} \
         --genomicsdb-workspace-path ~{genomicsDBWorkspacePath} \
@@ -754,6 +795,7 @@ task GenomicsDBImport {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -764,10 +806,11 @@ task GenomicsDBImport {
         genomicsDBWorkspacePath: {description: "Where the genomicsDB files should be stored", category: "advanced"}
         genomicsDBTarFile: {description: "Where the .tar file containing the genomicsDB should be stored", category: "advanced"}
         tmpDir: {description: "Alternate temporary directory in case there is not enough space. Must be mounted when using containers",
-        category: "advanced"}
+                 category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -787,15 +830,16 @@ task GenotypeGVCFs {
         File? dbsnpVCFIndex
         File? pedigree
 
-        String memory = "18G"
+        String memory = "7G"
         String javaXmx = "6G"
+        Int timeMinutes = 120 # This will likely be used with intervals, as such size based estimation can't be used.
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         GenotypeGVCFs \
         -R ~{referenceFasta} \
         -O ~{outputPath} \
@@ -815,6 +859,7 @@ task GenotypeGVCFs {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -835,6 +880,7 @@ task GenotypeGVCFs {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -850,14 +896,15 @@ task GetPileupSummaries {
         File sitesForContaminationIndex
         String outputPrefix
 
-        String memory = "24G"
+        String memory = "13G"
         String javaXmx = "12G"
+        Int timeMinutes = 120
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.2.0--1"
     }
 
     command {
         set -e
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         GetPileupSummaries \
         -I ~{sampleBam} \
         -V ~{variantsForContamination} \
@@ -871,6 +918,7 @@ task GetPileupSummaries {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -886,6 +934,7 @@ task GetPileupSummaries {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -913,15 +962,16 @@ task HaplotypeCaller {
         Boolean dontUseSoftClippedBases = false
         Float? standardMinConfidenceThresholdForCalling
 
-        String memory = "12G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 400 # This will likely be used with intervals, as such size based estimation can't be used.
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         HaplotypeCaller \
         -R ~{referenceFasta} \
         -O ~{outputPath} \
@@ -945,6 +995,7 @@ task HaplotypeCaller {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -974,6 +1025,7 @@ task HaplotypeCaller {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -984,14 +1036,15 @@ task LearnReadOrientationModel {
     input {
         Array[File]+ f1r2TarGz
 
-        String memory = "24G"
+        String memory = "13G"
         String javaXmx = "12G"
+        Int timeMinutes = 120
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.2.0--1"
     }
 
     command {
         set -e
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         LearnReadOrientationModel \
         -I ~{sep=" -I " f1r2TarGz} \
         -O "artifact-priors.tar.gz"
@@ -1003,6 +1056,7 @@ task LearnReadOrientationModel {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -1011,6 +1065,7 @@ task LearnReadOrientationModel {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1020,14 +1075,15 @@ task MergeStats {
     input {
         Array[File]+ stats
 
-        String memory = "28G"
+        String memory = "15G"
         String javaXmx = "14G"
+        Int timeMinutes = 30
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         MergeMutectStats \
         -stats ~{sep=" -stats " stats} \
         -O "merged.stats"
@@ -1039,6 +1095,7 @@ task MergeStats {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -1047,6 +1104,7 @@ task MergeStats {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1064,15 +1122,16 @@ task ModelSegments {
             else 30
         Int maximumNumberOfSmoothingIterations = 10
 
-        String memory = "64G"
+        String memory = "11G"
         String javaXmx = "10G"
+        Int timeMinutes = 60
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p ~{outputDir}
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         ModelSegments \
         --denoised-copy-ratios ~{denoisedCopyRatios} \
         --allelic-counts ~{allelicCounts} \
@@ -1099,6 +1158,7 @@ task ModelSegments {
 
     runtime {
         docker: dockerImage
+        time_minute: timeMinutes
         memory: memory
     }
 
@@ -1114,6 +1174,7 @@ task ModelSegments {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1137,15 +1198,16 @@ task MuTect2 {
         Array[File]+ intervals
         String outputStats = outputVcf + ".stats"
 
-        String memory = "16G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 240
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputVcf})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         Mutect2 \
         -R ~{referenceFasta} \
         -I ~{sep=" -I " inputBams} \
@@ -1167,6 +1229,7 @@ task MuTect2 {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -1189,6 +1252,7 @@ task MuTect2 {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1203,15 +1267,16 @@ task PlotDenoisedCopyRatios {
         File denoisedCopyRatios
         Int? minimumContigLength
 
-        String memory = "32G"
-        String javaXmx = "7G"
+        String memory = "4G"
+        String javaXmx = "3G"
+        Int timeMinutes = 2
         String dockerImage = "broadinstitute/gatk:4.1.4.0" # The biocontainer doesn't seem to contain R.
     }
 
     command {
         set -e
         mkdir -p ~{outputDir}
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         PlotDenoisedCopyRatios \
         --standardized-copy-ratios ~{standardizedCopyRatios} \
         --denoised-copy-ratios ~{denoisedCopyRatios} \
@@ -1232,6 +1297,7 @@ task PlotDenoisedCopyRatios {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -1245,6 +1311,7 @@ task PlotDenoisedCopyRatios {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1260,15 +1327,16 @@ task PlotModeledSegments {
         File allelicCounts
         Int? minimumContigLength
 
-        String memory = "21G"
-        String javaXmx = "7G"
+        String memory = "4G"
+        String javaXmx = "3G"
+        Int timeMinutes = 2
         String dockerImage = "broadinstitute/gatk:4.1.4.0" # The biocontainer doesn't seem to contain R.
     }
 
     command {
         set -e
         mkdir -p ~{outputDir}
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         PlotModeledSegments \
         --denoised-copy-ratios ~{denoisedCopyRatios} \
         --allelic-counts ~{allelicCounts} \
@@ -1285,6 +1353,7 @@ task PlotModeledSegments {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -1299,6 +1368,7 @@ task PlotModeledSegments {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1315,15 +1385,16 @@ task PreprocessIntervals {
         Int padding = if defined(intervals) then 250 else 0
         String intervalMergingRule = "OVERLAPPING_ONLY"
 
-        String memory = "10G"
-        String javaXmx = "2G"
+        String memory = "4G"
+        String javaXmx = "3G"
+        Int timeMinutes = 1 + ceil(size(referenceFasta, "G") * 6)
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputIntervalList})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         PreprocessIntervals \
         -R ~{referenceFasta} \
         --sequence-dictionary ~{referenceFastaDict} \
@@ -1340,6 +1411,7 @@ task PreprocessIntervals {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -1355,6 +1427,7 @@ task PreprocessIntervals {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1370,15 +1443,16 @@ task SelectVariants {
         String outputPath = "output.vcf.gz"
         String? selectTypeToInclude
         Array[File] intervals = []
-        String memory = "16G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 60
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         SelectVariants \
         -R ~{referenceFasta} \
         -V ~{inputVcf} \
@@ -1394,6 +1468,7 @@ task SelectVariants {
 
     runtime {
         docker: dockerImage
+        time_minute: timeMinutes
         memory: memory
     }
 
@@ -1412,6 +1487,7 @@ task SelectVariants {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1427,15 +1503,16 @@ task SplitNCigarReads {
         String outputBam
         Array[File] intervals = []
 
-        String memory = "16G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 120 # This will likely be used with intervals, as such size based estimation can't be used.
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputBam})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         SplitNCigarReads \
         -I ~{inputBam} \
         -R ~{referenceFasta} \
@@ -1450,6 +1527,7 @@ task SplitNCigarReads {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -1467,6 +1545,7 @@ task SplitNCigarReads {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -1483,15 +1562,16 @@ task VariantFiltration {
         Array[String]+ filterArguments
         Array[File] intervals = []
 
-        String memory = "16G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 120
         String dockerImage = "quay.io/biocontainers/gatk4:4.1.0.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPath})"
-        gatk --java-options -Xmx~{javaXmx} \
+        gatk --java-options '-Xmx~{javaXmx} -XX:ParallelGCThreads=1' \
         VariantFiltration \
         -I ~{inputVcf} \
         -R ~{referenceFasta} \
@@ -1507,6 +1587,7 @@ task VariantFiltration {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -1525,6 +1606,7 @@ task VariantFiltration {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/gffcompare.wdl b/gffcompare.wdl
index ca2b1669d64c2fe95c7068df00a8445fa9f6e21a..e5f62b5ec557ef05afbfcee0bb24d175a2b316b6 100644
--- a/gffcompare.wdl
+++ b/gffcompare.wdl
@@ -44,6 +44,7 @@ task GffCompare {
         Boolean verbose = false
         Boolean debugMode = false
 
+        Int timeMinutes = 1 + ceil(size(inputGtfFiles, "G") * 30)
         String dockerImage = "quay.io/biocontainers/gffcompare:0.10.6--h2d50403_0"
 
         # This workaround only works in the input section.
@@ -107,9 +108,11 @@ task GffCompare {
         File? missedIntrons = if debugMode
             then totalPrefix + ".missed_introns.gtf"
             else noneFile
+        Array[File] allFiles = select_all([annotated, loci, stats, tracking, redundant, missedIntrons])
     }
 
     runtime {
+       time_minutes: timeMinutes
        docker: dockerImage
     }
 
@@ -134,6 +137,7 @@ task GffCompare {
         noTmap: {description: "Equivalent to gffcompare's `-T` flag.", category: "advanced"}
         verbose: {description: "Equivalent to gffcompare's `-V` flag.", category: "advanced"}
         debugMode: {description: "Equivalent to gffcompare's `-D` flag.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/gffread.wdl b/gffread.wdl
index 6b23785c7ee37c0fb112ed59d45424d2bced07d0..d83e4d76564411d1edd8b3ef5a17ac208f8bad67 100644
--- a/gffread.wdl
+++ b/gffread.wdl
@@ -30,6 +30,7 @@ task GffRead {
         String? proteinFastaPath
         String? filteredGffPath
         Boolean outputGtfFormat = false
+        Int timeMinutes = 1 + ceil(size(inputGff) * 10)
         String dockerImage = "quay.io/biocontainers/gffread:0.9.12--0"
     }
 
@@ -62,6 +63,7 @@ task GffRead {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
@@ -73,6 +75,7 @@ task GffRead {
         proteinFastaPath: {description: "The location the protein fasta should be written to.", category: "advanced"}
         filteredGffPath: {description: "The location the filtered GFF should be written to.", category: "advanced"}
         outputGtfFormat: {description: "Equivalent to gffread's `-T` flag.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/hisat2.wdl b/hisat2.wdl
index b65b2da95379e83363654fc6a58893586ed4ee12..85bd3b353f4cc6c788b6530c25afd8c9c4606177 100644
--- a/hisat2.wdl
+++ b/hisat2.wdl
@@ -33,8 +33,9 @@ task Hisat2 {
         Boolean downstreamTranscriptomeAssembly = true
         String summaryFilePath = basename(outputBam, ".bam") + ".summary.txt"
 
-        Int threads = 1
-        String memory = "48G"
+        Int threads = 4
+        String memory = "~{threads + 5 + ceil(size(indexFiles, "G"))}G"
+        Int timeMinutes = 1 + ceil(size([inputR1, inputR2], "G") * 180 / threads)
         # quay.io/biocontainers/mulled-v2-a97e90b3b802d1da3d6958e0867610c718cb5eb1
         # is a combination of hisat2 and samtools
         # hisat2=2.1.0, samtools=1.8
@@ -56,7 +57,8 @@ task Hisat2 {
         --rg 'LB:~{library}' \
         --rg 'PL:~{platform}' \
         ~{true="--dta" false="" downstreamTranscriptomeAssembly} \
-        --new-summary ~{summaryFilePath} \
+        --new-summary \
+        --summary-file ~{summaryFilePath} \
         | samtools sort > ~{outputBam}
         samtools index ~{outputBam} ~{bamIndexPath}
     }
@@ -70,6 +72,7 @@ task Hisat2 {
     runtime {
         memory: memory
         cpu: threads + 1
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -85,6 +88,7 @@ task Hisat2 {
         downstreamTranscriptomeAssembly: {description: "Equivalent to hisat2's `--dta` flag.", category: "advanced"}
         threads: {description: "The number of threads to use.", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/htseq.wdl b/htseq.wdl
index 900a88a79b96fab968b1244d0b3d6e090db70df5..35faeef3a1158634cfdbff45f663bab9d40d035e 100644
--- a/htseq.wdl
+++ b/htseq.wdl
@@ -33,6 +33,7 @@ task HTSeqCount {
         Array[String] additionalAttributes = []
 
         String memory = "40G"
+        Int timeMinutes = 10 + ceil(size(inputBams, "G") * 60)
         String dockerImage = "quay.io/biocontainers/htseq:0.11.2--py37h637b7d7_1"
     }
 
@@ -56,54 +57,24 @@ task HTSeqCount {
     }
 
     runtime {
+        time_minutes: timeMinutes
         memory: memory
         docker: dockerImage
     }
 
     parameter_meta {
-        inputBams: {
-            description: "The input BAM files.",
-            category: "required"
-        }
-        gtfFile: {
-            description: "A GTF/GFF file containing the features of interest.",
-            category: "required"
-        }
-        outputTable: {
-            description: "The path to which the output table should be written.",
-            category: "common"
-        }
-        format: {
-            description: "Equivalent to the -f option of htseq-count.",
-            category: "advanced"
-        }
-        order: {
-            description: "Equivalent to the -r option of htseq-count.",
-            category: "advanced"
-        }
-        stranded: {
-            description: "Equivalent to the -s option of htseq-count.",
-            category: "common"
-        }
-        featureType: {
-            description: "Equivalent to the --type option of htseq-count.",
-            category: "advanced"
-        }
-        idattr: {
-            description: "Equivalent to the --idattr option of htseq-count.",
-            category: "advanced"
-        }
-        additionalAttributes: {
-            description: "Equivalent to the --additional-attr option of htseq-count.",
-            category: "advanced"
-        }
-        memory: {
-            description: "The amount of memory the job requires in GB.",
-            category: "advanced"
-        }
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        inputBams: {description: "The input BAM files.", category: "required"}
+        gtfFile: {description: "A GTF/GFF file containing the features of interest.", category: "required"}
+        outputTable: {description: "The path to which the output table should be written.", category: "common"}
+        format: {description: "Equivalent to the -f option of htseq-count.", category: "advanced"}
+        order: {description: "Equivalent to the -r option of htseq-count.", category: "advanced"}
+        stranded: {description: "Equivalent to the -s option of htseq-count.", category: "common"}
+        featureType: {description: "Equivalent to the --type option of htseq-count.", category: "advanced"}
+        idattr: {description: "Equivalent to the --idattr option of htseq-count.", category: "advanced"}
+        additionalAttributes: {description: "Equivalent to the --additional-attr option of htseq-count.", category: "advanced"}
+        memory: {description: "The amount of memory the job requires in GB.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
diff --git a/isoseq3.wdl b/isoseq3.wdl
index 10d87bbc2264ac1aad7661f8ab8786249503684a..9e0dfdb2f43d4ba4ea2dd1807eb152ece5a15446 100644
--- a/isoseq3.wdl
+++ b/isoseq3.wdl
@@ -32,6 +32,7 @@ task Refine {
 
         Int cores = 2
         String memory = "2G"
+        Int timeMinutes = 30
         String dockerImage = "quay.io/biocontainers/isoseq3:3.3.0--0"
     }
 
@@ -61,6 +62,7 @@ task Refine {
     runtime {
         cpu: cores
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -75,6 +77,7 @@ task Refine {
         outputNamePrefix: {description: "Basename of the output files.", category: "required"}
         cores: {description: "The number of cores to be used.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
diff --git a/lima.wdl b/lima.wdl
index ba8a5407fa1be7757beaff0b5bdb404016793352..ddd37da4237296c40349fa4d6b3b553924fbaadd 100644
--- a/lima.wdl
+++ b/lima.wdl
@@ -50,6 +50,7 @@ task Lima {
         
         Int cores = 2
         String memory = "2G"
+        Int timeMinutes = 30
         String dockerImage = "quay.io/biocontainers/lima:1.11.0--0"
     }
 
@@ -110,6 +111,7 @@ task Lima {
     runtime {
         cpu: cores
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -142,6 +144,7 @@ task Lima {
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         cores: {description: "The number of cores to be used.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
diff --git a/manta.wdl b/manta.wdl
index 5006a01efb5d92a97d527fa26b5866db959c3329..5382d2a5b6ad067efe9ba395ff7ab48077630f83 100644
--- a/manta.wdl
+++ b/manta.wdl
@@ -33,6 +33,7 @@ task Germline {
 
         Int cores = 1
         Int memoryGb = 4
+        Int timeMinutes = 60
         String dockerImage = "quay.io/biocontainers/manta:1.4.0--py27_1"
     }
 
@@ -60,6 +61,7 @@ task Germline {
         cpu: cores
         memory: "~{memoryGb}G"
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
@@ -74,6 +76,7 @@ task Germline {
         exome: {description: "Whether or not the data is from exome sequencing.", category: "common"}
         cores: {description: "The the number of cores required to run a program", category: "required"}
         memoryGb: {description: "The memory required to run the manta", category: "required"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }
@@ -93,6 +96,7 @@ task Somatic {
 
         Int cores = 1
         Int memoryGb = 4
+        Int timeMinutes = 60
         String dockerImage = "quay.io/biocontainers/manta:1.4.0--py27_1"
     }
 
@@ -130,6 +134,7 @@ task Somatic {
         cpu: cores
         memory: "~{memoryGb}G"
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
@@ -145,6 +150,7 @@ task Somatic {
         exome: {description: "Whether or not the data is from exome sequencing.", category: "common"}
         cores: {description: "The number of cores to use.", category: "advanced"}
         memoryGb: {description: "The amount of memory this job will use in Gigabytes.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }
diff --git a/minimap2.wdl b/minimap2.wdl
index fd28d4a9b0eed78dd8c52db211f1eea81246f1da..04b02bf2bdc7454c8e7c772063f1999e672a4d30 100644
--- a/minimap2.wdl
+++ b/minimap2.wdl
@@ -32,6 +32,7 @@ task Indexing {
 
         Int cores = 1
         String memory = "4G"
+        Int timeMinutes = 10
         String dockerImage = "quay.io/biocontainers/minimap2:2.17--h84994c4_0"
     }
 
@@ -55,6 +56,7 @@ task Indexing {
     runtime {
         cpu: cores
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -68,6 +70,7 @@ task Indexing {
         splitIndex: {description: "Split index for every ~NUM input bases.", category: "advanced"}
         cores: {description: "The number of cores to be used.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # output
@@ -96,6 +99,7 @@ task Mapping {
 
         Int cores = 4
         String memory = "30G"
+        Int timeMinutes = 1 + ceil(size(queryFile, "G") * 200 / cores)
         String dockerImage = "quay.io/biocontainers/minimap2:2.17--h84994c4_0"
     }
 
@@ -128,6 +132,7 @@ task Mapping {
     runtime {
         cpu: cores
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -149,6 +154,7 @@ task Mapping {
         queryFile: {description: "Input fasta file.", category: "required"}
         cores: {description: "The number of cores to be used.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # output
diff --git a/multiqc.wdl b/multiqc.wdl
index b50122e0a51b7fd714407ca692377af314f901ce..62ca5421cfb6e3062fc0997be6ca8fa605207302 100644
--- a/multiqc.wdl
+++ b/multiqc.wdl
@@ -53,7 +53,7 @@ task MultiQC {
         String? clConfig
     
         String memory = "4G"
-
+        Int timeMinutes = 120
         String dockerImage = "quay.io/biocontainers/multiqc:1.7--py_1"
     }
 
@@ -133,6 +133,7 @@ task MultiQC {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -170,6 +171,7 @@ task MultiQC {
         finished: {description: "An array of booleans that can be used to let multiqc wait on stuff.", category: "internal_use_only"}
 
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/picard.wdl b/picard.wdl
index e92755045485b108a502025e5d2f6112ccc40264..3103ad9baa7287a211a652e892dfa45a1071bebc 100644
--- a/picard.wdl
+++ b/picard.wdl
@@ -26,15 +26,16 @@ task BedToIntervalList {
         File dict
         String outputPath = "regions.interval_list"
 
-        String memory = "12G"
-        String javaXmx = "4G"
+        String memory = "4G"
+        String javaXmx = "3G"
+        Int timeMinutes = 5
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPath})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         BedToIntervalList \
         I=~{bedFile} \
         O=~{outputPath} \
@@ -47,6 +48,7 @@ task BedToIntervalList {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -54,11 +56,11 @@ task BedToIntervalList {
         # inputs
         bedFile: {description: "A bed file.", category: "required"}
         dict: {description: "A sequence dict file.", category: "required"}
-        outputPath: {description: "The location the output interval list should be written to.",
-                     category: "advanced"}
+        outputPath: {description: "The location the output interval list should be written to.", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -83,8 +85,9 @@ task CollectMultipleMetrics {
         Boolean collectSequencingArtifactMetrics = true
         Boolean collectQualityYieldMetrics = true
 
-        String memory = "32G"
+        String memory = "9G"
         String javaXmx = "8G"
+        Int timeMinutes = 1 + ceil(size(inputBam, "G") * 6)
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
@@ -92,7 +95,7 @@ task CollectMultipleMetrics {
     command {
         set -e
         mkdir -p "$(dirname ~{basename})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         CollectMultipleMetrics \
         I=~{inputBam} \
         R=~{referenceFasta} \
@@ -110,24 +113,24 @@ task CollectMultipleMetrics {
     }
 
     output {
-        File alignmentSummary = basename + ".alignment_summary_metrics"
-        File baitBiasDetail = basename + ".bait_bias_detail_metrics"
-        File baitBiasSummary = basename + ".bait_bias_summary_metrics"
-        File baseDistributionByCycle = basename + ".base_distribution_by_cycle_metrics"
+        File? alignmentSummary = basename + ".alignment_summary_metrics"
+        File? baitBiasDetail = basename + ".bait_bias_detail_metrics"
+        File? baitBiasSummary = basename + ".bait_bias_summary_metrics"
+        File? baseDistributionByCycle = basename + ".base_distribution_by_cycle_metrics"
         File? baseDistributionByCyclePdf = basename + ".base_distribution_by_cycle.pdf"
-        File errorSummary = basename + ".error_summary_metrics"
-        File gcBiasDetail = basename + ".gc_bias.detail_metrics"
-        File gcBiasPdf = basename + ".gc_bias.pdf"
-        File gcBiasSummary = basename + ".gc_bias.summary_metrics"
+        File? errorSummary = basename + ".error_summary_metrics"
+        File? gcBiasDetail = basename + ".gc_bias.detail_metrics"
+        File? gcBiasPdf = basename + ".gc_bias.pdf"
+        File? gcBiasSummary = basename + ".gc_bias.summary_metrics"
         File? insertSizeHistogramPdf = basename + ".insert_size_histogram.pdf"
         File? insertSize = basename + ".insert_size_metrics"
-        File preAdapterDetail = basename + ".pre_adapter_detail_metrics"
-        File preAdapterSummary = basename + ".pre_adapter_summary_metrics"
-        File qualityByCycle = basename + ".quality_by_cycle_metrics"
+        File? preAdapterDetail = basename + ".pre_adapter_detail_metrics"
+        File? preAdapterSummary = basename + ".pre_adapter_summary_metrics"
+        File? qualityByCycle = basename + ".quality_by_cycle_metrics"
         File? qualityByCyclePdf = basename + ".quality_by_cycle.pdf"
-        File qualityDistribution = basename + ".quality_distribution_metrics"
+        File? qualityDistribution = basename + ".quality_distribution_metrics"
         File? qualityDistributionPdf = basename + ".quality_distribution.pdf"
-        File qualityYield = basename + ".quality_yield_metrics"
+        File? qualityYield = basename + ".quality_yield_metrics"
         # Using a glob is easier. But will lead to very ugly output directories.
         Array[File] allStats = select_all([
             alignmentSummary,
@@ -153,33 +156,29 @@ task CollectMultipleMetrics {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
     parameter_meta {
         # inputs
-        inputBam: {description: "The input BAM file for which metrics will be collected.",
-                   category: "required"}
+        inputBam: {description: "The input BAM file for which metrics will be collected.", category: "required"}
         inputBamIndex: {description: "The index of the input BAM file.", category: "required"}
-        referenceFasta: {description: "The reference fasta file which was also used for mapping.",
-                         category: "required"}
+        referenceFasta: {description: "The reference fasta file which was also used for mapping.", category: "required"}
         referenceFastaDict: {description: "The sequence dictionary associated with the reference fasta file.",
                              category: "required"}
         referenceFastaFai: {description: "The index for the reference fasta file.", category: "required"}
-        basename: {description: "The basename/prefix of the output files (may include directories).",
-                   category: "required"}
+        basename: {description: "The basename/prefix of the output files (may include directories).", category: "required"}
         collectAlignmentSummaryMetrics: {description: "Equivalent to the `PROGRAM=CollectAlignmentSummaryMetrics` argument.",
                                          category: "advanced"}
         collectInsertSizeMetrics: {description: "Equivalent to the `PROGRAM=CollectInsertSizeMetrics` argument.",
                                    category: "advanced"}
         qualityScoreDistribution: {description: "Equivalent to the `PROGRAM=QualityScoreDistribution` argument.",
                                    category: "advanced"}
-        meanQualityByCycle: {description: "Equivalent to the `PROGRAM=MeanQualityByCycle` argument.",
-                             category: "advanced"}
+        meanQualityByCycle: {description: "Equivalent to the `PROGRAM=MeanQualityByCycle` argument.", category: "advanced"}
         collectBaseDistributionByCycle: {description: "Equivalent to the `PROGRAM=CollectBaseDistributionByCycle` argument.",
                                          category: "advanced"}
-        collectGcBiasMetrics: {description: "Equivalent to the `PROGRAM=CollectGcBiasMetrics` argument.",
-                               category: "advanced"}
+        collectGcBiasMetrics: {description: "Equivalent to the `PROGRAM=CollectGcBiasMetrics` argument.", category: "advanced"}
         collectSequencingArtifactMetrics: {description: "Equivalent to the `PROGRAM=CollectSequencingArtifactMetrics` argument.",
                                            category: "advanced"}
         collectQualityYieldMetrics: {description: "Equivalent to the `PROGRAM=CollectQualityYieldMetrics` argument.",
@@ -188,6 +187,7 @@ task CollectMultipleMetrics {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -201,8 +201,9 @@ task CollectRnaSeqMetrics {
         String basename
         String strandSpecificity = "NONE"
 
-        String memory = "32G"
+        String memory = "9G"
         String javaXmx =  "8G"
+        Int timeMinutes = 1 + ceil(size(inputBam, "G") * 6)
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
@@ -210,7 +211,7 @@ task CollectRnaSeqMetrics {
         set -e
         mkdir -p "$(dirname ~{basename})"
         picard -Xmx~{javaXmx} \
-        CollectRnaSeqMetrics \
+        CollectRnaSeqMetrics -XX:ParallelGCThreads=1 \
         I=~{inputBam} \
         O=~{basename}.RNA_Metrics \
         CHART_OUTPUT=~{basename}.RNA_Metrics.pdf \
@@ -225,23 +226,23 @@ task CollectRnaSeqMetrics {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
     parameter_meta {
         # inputs
-        inputBam: {description: "The input BAM file for which metrics will be collected.",
-                   category: "required"}
+        inputBam: {description: "The input BAM file for which metrics will be collected.", category: "required"}
         inputBamIndex: {description: "The index of the input BAM file.", category: "required"}
         refRefflat: {description: "A refflat file containing gene annotations.", catehory: "required"}
-        basename: {description: "The basename/prefix of the output files (may include directories).",
-                   category: "required"}
+        basename: {description: "The basename/prefix of the output files (may include directories).", category: "required"}
         strandSpecificity: {description: "Equivalent to the `STRAND_SPECIFICITY` option of picard's CollectRnaSeqMetrics.",
                             category: "common"}
 
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -258,15 +259,16 @@ task CollectTargetedPcrMetrics {
         Array[File]+ targetIntervals
         String basename
 
-        String memory = "12G"
-        String javaXmx = "4G"
+        String memory = "4G"
+        String javaXmx = "3G"
+        Int timeMinutes = 1 + ceil(size(inputBam, "G") * 6)
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{basename})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         CollectTargetedPcrMetrics \
         I=~{inputBam} \
         R=~{referenceFasta} \
@@ -285,16 +287,15 @@ task CollectTargetedPcrMetrics {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
     parameter_meta {
         # inputs
-        inputBam: {description: "The input BAM file for which metrics will be collected.",
-                   category: "required"}
+        inputBam: {description: "The input BAM file for which metrics will be collected.", category: "required"}
         inputBamIndex: {description: "The index of the input BAM file.", category: "required"}
-        referenceFasta: {description: "The reference fasta file which was also used for mapping.",
-                         category: "required"}
+        referenceFasta: {description: "The reference fasta file which was also used for mapping.", category: "required"}
         referenceFastaDict: {description: "The sequence dictionary associated with the reference fasta file.",
                              category: "required"}
         referenceFastaFai: {description: "The index for the reference fasta file.", category: "required"}
@@ -302,12 +303,12 @@ task CollectTargetedPcrMetrics {
                            category: "required"}
         targetIntervals: {description: "An interval list describing the coordinates of the targets sequenced.",
                           category: "required"}
-        basename: {description: "The basename/prefix of the output files (may include directories).",
-                   category: "required"}
+        basename: {description: "The basename/prefix of the output files (may include directories).", category: "required"}
 
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -362,15 +363,16 @@ task GatherBamFiles {
         Array[File]+ inputBamsIndex
         String outputBamPath
 
-        String memory = "12G"
-        String javaXmx = "4G"
+        String memory = "4G"
+        String javaXmx = "3G"
+        Int timeMinutes = 1 + ceil(size(inputBams, "G") * 0.5)
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputBamPath})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         GatherBamFiles \
         INPUT=~{sep=' INPUT=' inputBams} \
         OUTPUT=~{outputBamPath} \
@@ -386,6 +388,7 @@ task GatherBamFiles {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -398,6 +401,7 @@ task GatherBamFiles {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -409,15 +413,16 @@ task GatherVcfs {
         Array[File]+ inputVcfIndexes
         String outputVcfPath = "out.vcf.gz"
 
-        String memory = "12G"
+        String memory = "5G"
         String javaXmx = "4G"
+        Int timeMinutes = 1 + ceil(size(inputVcfs, "G") * 2)
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputVcfPath})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         GatherVcfs \
         INPUT=~{sep=' INPUT=' inputVcfs} \
         OUTPUT=~{outputVcfPath}
@@ -430,6 +435,7 @@ task GatherVcfs {
     runtime {
         docker: dockerImage
         memory: memory
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
@@ -441,6 +447,7 @@ task GatherVcfs {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -454,8 +461,9 @@ task MarkDuplicates {
         String outputBamPath
         String metricsPath
 
-        String memory = "24G"
+        String memory = "9G"
         String javaXmx = "8G"
+        Int timeMinutes = 1 + ceil(size(inputBams, "G") * 8)
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
 
         # The program default for READ_NAME_REGEX is appropriate in nearly every case.
@@ -473,7 +481,7 @@ task MarkDuplicates {
     command {
         set -e
         mkdir -p "$(dirname ~{outputBamPath})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         MarkDuplicates \
         INPUT=~{sep=' INPUT=' inputBams} \
         OUTPUT=~{outputBamPath} \
@@ -496,6 +504,7 @@ task MarkDuplicates {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -510,6 +519,7 @@ task MarkDuplicates {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -522,8 +532,9 @@ task MergeVCFs {
         Array[File]+ inputVCFsIndexes
         String outputVcfPath
 
-        String memory = "24G"
-        String javaXmx = "8G"
+        String memory = "5G"
+        String javaXmx = "4G"
+        Int timeMinutes = 1 + ceil(size(inputVCFs, "G"))
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
@@ -533,7 +544,7 @@ task MergeVCFs {
     command {
         set -e
         mkdir -p "$(dirname ~{outputVcfPath})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         MergeVcfs \
         INPUT=~{sep=' INPUT=' inputVCFs} \
         OUTPUT=~{outputVcfPath}
@@ -546,6 +557,7 @@ task MergeVCFs {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -558,6 +570,7 @@ task MergeVCFs {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -569,7 +582,7 @@ task SamToFastq {
         File inputBamIndex
         Boolean paired = true
 
-        String memory = "48G"
+        String memory = "17G"
         String javaXmx = "16G" # High memory default to avoid crashes.
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
         File? NONE
@@ -581,7 +594,7 @@ task SamToFastq {
 
     command {
         set -e
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         SamToFastq \
         I=~{inputBam} \
         ~{"FASTQ=" + outputRead1} \
@@ -606,15 +619,15 @@ task ScatterIntervalList {
         File interval_list
         Int scatter_count
 
-        String memory = "12G"
-        String javaXmx = "4G"
+        String memory = "4G"
+        String javaXmx = "3G"
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
     command {
         set -e
         mkdir scatter_list
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         IntervalListTools \
         SCATTER_COUNT=~{scatter_count} \
         SUBDIVISION_MODE=BALANCING_WITHOUT_INTERVAL_SUBDIVISION_WITH_OVERFLOW \
@@ -641,8 +654,9 @@ task SortVcf {
         String outputVcfPath
         File? dict
 
-        String memory = "24G"
+        String memory = "9G"
         String javaXmx = "8G"
+        Int timeMinutes = 1 + ceil(size(vcfFiles, "G") * 5)
         String dockerImage = "quay.io/biocontainers/picard:2.20.5--0"
     }
 
@@ -650,7 +664,7 @@ task SortVcf {
     command {
         set -e
         mkdir -p "$(dirname ~{outputVcfPath})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         SortVcf \
         I=~{sep=" I=" vcfFiles} \
         ~{"SEQUENCE_DICTIONARY=" + dict} \
@@ -664,6 +678,7 @@ task SortVcf {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -676,6 +691,7 @@ task SortVcf {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -686,15 +702,16 @@ task RenameSample {
         File inputVcf
         String outputPath = "./picard/renamed.vcf"
         String newSampleName
-        String memory = "24G"
+        String memory = "9G"
         String javaXmx = "8G"
+        Int timeMinutes = 1 + ceil(size(inputVcf, "G") * 2)
         String dockerImage = "quay.io/biocontainers/picard:2.19.0--0"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPath})"
-        picard -Xmx~{javaXmx} \
+        picard -Xmx~{javaXmx} -XX:ParallelGCThreads=1 \
         RenameSampleInVcf \
         I=~{inputVcf} \
         O=~{outputPath} \
@@ -707,6 +724,7 @@ task RenameSample {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -717,6 +735,7 @@ task RenameSample {
         newSampleName: {description: "A string to replace the old sample name.", category: "required"}
         memory: {description: "The memory required to run the programs", category: "advanced"}
         javaXmx: {description: "The max. memory allocated for JAVA", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }
diff --git a/rtg.wdl b/rtg.wdl
index 8fd53ca4a4324b388c6f18c1c0584a26d013fe66..104a5ef9f29811ffde4d81a3b96da77d5bf728fc 100644
--- a/rtg.wdl
+++ b/rtg.wdl
@@ -27,7 +27,8 @@ task Format {
         Array[File]+ inputFiles
         String dockerImage = "quay.io/biocontainers/rtg-tools:3.10.1--0"
         String rtgMem = "8G"
-        String memory = "16G"
+        String memory = "9G"
+        Int timeMinutes = 1 + ceil(size(inputFiles) * 2)
     }
 
     command {
@@ -45,15 +46,17 @@ task Format {
     runtime {
         docker: dockerImage
         memory: memory
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
-        format: {description: "Format of input. Allowed values are [fasta, fastq, fastq-interleaved, sam-se, sam-pe] (Default is fasta)",
+        format: {description: "Format of input. Allowed values are [fasta, fastq, fastq-interleaved, sam-se, sam-pe].",
                  category: "advanced"}
         outputPath: {description: "Where the output should be placed.", category: "advanced"}
         inputFiles: {description: "input sequence files. May be specified 1 or more times.", category: "required"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-              category: "advanced"}
+                      category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         rtgMem: {description: "The amount of memory rtg will allocate to the JVM", category: "advanced"}
     }
@@ -77,7 +80,8 @@ task VcfEval {
         String outputMode = "split"
         Int threads = 1  # tool default is number of cores in the system 😱
         String rtgMem = "8G"
-        String memory = "16G"
+        String memory = "9G"
+        Int timeMinutes = 1 + ceil(size([baseline, calls], "G") * 5)
         String dockerImage = "quay.io/biocontainers/rtg-tools:3.10.1--0"
     }
 
@@ -131,6 +135,7 @@ task VcfEval {
         docker: dockerImage
         cpu: threads
         memory: memory
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
@@ -157,6 +162,7 @@ task VcfEval {
         threads: {description: "Number of threads. Default is 1", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
               category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         rtgMem: {description: "The amount of memory rtg will allocate to the JVM", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
     }
diff --git a/samtools.wdl b/samtools.wdl
index 5521c6aaa5f93badddc571acf400f52afa98de1f..5648eb1cf403fbe3c877fe72f3cae066514d7026 100644
--- a/samtools.wdl
+++ b/samtools.wdl
@@ -26,6 +26,7 @@ task BgzipAndIndex {
         String outputDir
         String type = "vcf"
 
+        Int timeMinutes = 1 + ceil(size(inputFile, "G"))
         String dockerImage = "quay.io/biocontainers/tabix:0.2.6--ha92aebf_0"
     }
 
@@ -44,7 +45,8 @@ task BgzipAndIndex {
     }
 
     runtime {
-       docker: dockerImage
+        time_minutes: timeMinutes
+        docker: dockerImage
     }
 
     parameter_meta {
@@ -52,6 +54,7 @@ task BgzipAndIndex {
         inputFile: {description: "The file to be compressed and indexed.", category: "required"}
         outputDir: {description: "The directory in which the output will be placed.", category: "required"}
         type: {description: "The type of file (eg. vcf or bed) to be compressed and indexed.", category: "common"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -95,131 +98,195 @@ task Faidx {
     }
 }
 
-task Index {
+task Fastq {
     input {
-        File bamFile
-        String? outputBamPath
+        File inputBam
+        String outputRead1
+        String? outputRead2
+        String? outputRead0
+        Int? includeFilter
+        Int? excludeFilter
+        Int? excludeSpecificFilter
+        Boolean appendReadNumber = false
+        Boolean outputQuality = false
+        Int? compressionLevel
+
+        Int threads = 1
+        String memory = "1G"
+        Int timeMinutes = 1 + ceil(size(inputBam) * 2)
         String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
     }
 
-    # Select_first is needed, otherwise womtool validate fails.
-    String outputPath = select_first([outputBamPath, basename(bamFile)])
-    String bamIndexPath = sub(outputPath, "\.bam$", ".bai")
-
     command {
-        bash -c '
-        set -e
-        # Make sure outputBamPath does not exist.
-        if [ ! -f ~{outputPath} ]
-        then
-            mkdir -p "$(dirname ~{outputPath})"
-            ln ~{bamFile} ~{outputPath}
-        fi
-        samtools index ~{outputPath} ~{bamIndexPath}
-        '
+        samtools fastq \
+        ~{true="-1" false="-s" defined(outputRead2)} ~{outputRead1} \
+        ~{"-2 " + outputRead2} \
+        ~{"-0 " + outputRead0} \
+        ~{"-f " + includeFilter} \
+        ~{"-F " + excludeFilter} \
+        ~{"-G " + excludeSpecificFilter} \
+        ~{true="-N" false="-n" appendReadNumber} \
+        ~{true="-O" false="" outputQuality} \
+        ~{"-c " + compressionLevel} \
+        ~{"--threads " + threads} \
+        ~{inputBam}
     }
 
     output {
-        File indexedBam = outputPath
-        File index =  bamIndexPath
+        File read1 = outputRead1
+        File? read2 = outputRead2
+        File? read0 = outputRead0
     }
 
     runtime {
+        cpu: threads
+        memory: memory
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
         # inputs
-        bamFile: {description: "The BAM file for which an index should be made.", category: "required"}
-        outputBamPath: {description: "The location where the BAM file should be written to. The index will appear alongside this link to the BAM file.",
-                        category: "common"}
+        inputBam: {description: "The bam file to process.", category: "required"}
+        outputRead1: {description: "The location the reads (first reads for pairs, in case of paired-end sequencing) should be written to.", category: "required"}
+        outputRead2: {description: "The location the second reads from pairs should be written to.", category: "common"}
+        outputRead0: {description: "The location the unpaired reads should be written to (in case of paired-end sequenicng).", category: "advanced"}
+        includeFilter: {description: "Include reads with ALL of these flags. Corresponds to `-f`", category: "advanced"}
+        excludeFilter: {description: "Exclude reads with ONE OR MORE of these flags. Corresponds to `-F`", category: "advanced"}
+        excludeSpecificFilter: {description: "Exclude reads with ALL of these flags. Corresponds to `-G`", category: "advanced"}
+        appendReadNumber: {description: "Append /1 and /2 to the read name, or don't. Corresponds to `-n/N`", category: "advanced"}
+        outputQuality: {description: "Equivalent to samtools fastq's `-O` flag.", category: "advanced"}
+        threads: {description: "The number of threads to use.", category: "advanced"}
+        memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
 }
 
-task Merge {
+task FilterShortReadsBam {
     input {
-        Array[File]+ bamFiles
-        String outputBamPath = "merged.bam"
-        Boolean force = true
-
+        File bamFile
+        String outputPathBam
+        String memory = "1G"
+        Int timeMinutes = 1 + ceil(size(bamFile, "G") * 8)
         String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
     }
-    String indexPath = sub(outputBamPath, "\.bam$",".bai")
+
+    String outputPathBamIndex = sub(outputPathBam, "\.bam$", ".bai")
 
     command {
         set -e
-        mkdir -p "$(dirname ~{outputBamPath})"
-        samtools merge ~{true="-f" false="" force} ~{outputBamPath} ~{sep=' ' bamFiles}
-        samtools index ~{outputBamPath} ~{indexPath}
+        mkdir -p "$(dirname ~{outputPathBam})"
+        samtools view -h ~{bamFile} | \
+        awk 'length($10) > 30 || $1 ~/^@/' | \
+        samtools view -bS -> ~{outputPathBam}
+        samtools index ~{outputPathBam} ~{outputPathBamIndex}
     }
 
     output {
-        File outputBam = outputBamPath
-        File outputBamIndex = indexPath
+        File filteredBam = outputPathBam
+        File filteredBamIndex = outputPathBamIndex
     }
 
     runtime {
+        memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
-        # inputs
-        bamFiles: {description: "The BAM files to merge.", category: "required"}
-        outputBamPath: {description: "The location the merged BAM file should be written to.", category: "common"}
-        force: {description: "Equivalent to samtools merge's `-f` flag.", category: "advanced"}
-        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-                      category: "advanced"}
+        bamFile: {description: "The bam file to process.", category: "required"}
+        outputPathBam: {description: "The filtered bam file.", category: "common"}
+        memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }
 
-task Sort {
+task Flagstat {
     input {
         File inputBam
         String outputPath
-        Boolean sortByName = false
-        Int compressionLevel = 1
-
-        String memory = "2G"
-        String dockerImage = "quay.io/biocontainers/samtools:1.10--h9402c20_2"
 
-        Int? threads
+        String memory = "1G"
+        Int timeMinutes = 1 + ceil(size(inputBam, "G"))
+        String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
     }
 
     command {
         set -e
         mkdir -p "$(dirname ~{outputPath})"
-        samtools sort \
-        -l ~{compressionLevel} \
-        ~{true="-n" false="" sortByName} \
-        ~{"--threads " + threads} \
-        -o ~{outputPath} \
-        ~{inputBam}
+        samtools flagstat ~{inputBam} > ~{outputPath}
     }
 
     output {
-        File outputSortedBam = outputPath
+        File flagstat = outputPath
     }
 
     runtime {
-        cpu: 1 + select_first([threads, 0])
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
         # inputs
-        inputBam: {description: "The input SAM file.", category: "required"}
-        outputPath: {description: "Output directory path + output file.", category: "required"}
-        sortByName: {description: "Sort the inputBam by read name instead of position.", category: "advanced"}
-        compressionLevel: {description: "Compression level from 0 (uncompressed) to 9 (best).", category: "advanced"}
-        memory: {description: "The amount of memory available to the job.", category: "advanced"}
-        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
-        threads: {description: "The number of additional threads that will be used for this task.", category: "advanced"}
+        inputBam: {description: "The BAM file for which statistics should be retrieved.", category: "required"}
+        outputPath: {description: "The location the ouput should be written to.", category: "required"}
+        memory: {description: "The amount of memory needed for the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
+    }
+}
 
-        # outputs
-        outputSortedBam: {description: "Sorted BAM file."}
+task Index {
+    input {
+        File bamFile
+        String? outputBamPath
+        String memory = "2G"
+        Int timeMinutes = 1 + ceil(size(bamFile, "G") * 4)
+        String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
+    }
+
+    # Select_first is needed, otherwise womtool validate fails.
+    String outputPath = select_first([outputBamPath, basename(bamFile)])
+    String bamIndexPath = sub(outputPath, "\.bam$", ".bai")
+
+    command {
+        bash -c '
+        set -e
+        # Make sure outputBamPath does not exist.
+        if [ ! -f ~{outputPath} ]
+        then
+            mkdir -p "$(dirname ~{outputPath})"
+            ln ~{bamFile} ~{outputPath}
+        fi
+        samtools index ~{outputPath} ~{bamIndexPath}
+        '
+    }
+
+    output {
+        File indexedBam = outputPath
+        File index =  bamIndexPath
+    }
+
+    runtime {
+        memory: memory
+        time_minutes: timeMinutes
+        docker: dockerImage
+    }
+
+    parameter_meta {
+        # inputs
+        bamFile: {description: "The BAM file for which an index should be made.", category: "required"}
+        outputBamPath: {description: "The location where the BAM file should be written to. The index will appear alongside this link to the BAM file.",
+                        category: "common"}
+        memory: {description: "The amount of memory needed for the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
 
@@ -228,6 +295,7 @@ task Markdup {
         File inputBam
         String outputBamPath
 
+        Int timeMinutes = 1 + ceil(size(inputBam, "G") * 2)
         String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
     }
 
@@ -243,108 +311,105 @@ task Markdup {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
         # inputs
         inputBam: {description: "The BAM file to be processed.", category: "required"}
         outputBamPath: {description: "The location of the output BAM file.", category: "required"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
 }
 
-task Flagstat {
+task Merge {
     input {
-        File inputBam
-        String outputPath
+        Array[File]+ bamFiles
+        String outputBamPath = "merged.bam"
+        Boolean force = true
 
+        Int timeMinutes = 1 + ceil(size(bamFiles, "G") * 2)
         String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
     }
+    String indexPath = sub(outputBamPath, "\.bam$",".bai")
 
     command {
         set -e
-        mkdir -p "$(dirname ~{outputPath})"
-        samtools flagstat ~{inputBam} > ~{outputPath}
+        mkdir -p "$(dirname ~{outputBamPath})"
+        samtools merge ~{true="-f" false="" force} ~{outputBamPath} ~{sep=' ' bamFiles}
+        samtools index ~{outputBamPath} ~{indexPath}
     }
 
     output {
-        File flagstat = outputPath
+        File outputBam = outputBamPath
+        File outputBamIndex = indexPath
     }
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
         # inputs
-        inputBam: {description: "The BAM file for which statistics should be retrieved.", category: "required"}
-        outputPath: {description: "The location the ouput should be written to.", category: "required"}
+        bamFiles: {description: "The BAM files to merge.", category: "required"}
+        outputBamPath: {description: "The location the merged BAM file should be written to.", category: "common"}
+        force: {description: "Equivalent to samtools merge's `-f` flag.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
 }
 
-task Fastq {
+task Sort {
     input {
         File inputBam
-        String outputRead1
-        String? outputRead2
-        String? outputRead0
-        Int? includeFilter
-        Int? excludeFilter
-        Int? excludeSpecificFilter
-        Boolean appendReadNumber = false
-        Boolean outputQuality = false
-        Int? compressionLevel
+        String outputPath
+        Boolean sortByName = false
+        Int compressionLevel = 1
 
-        Int threads = 1
-        String memory = "1G"
-        String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
+        String memory = "2G"
+        String dockerImage = "quay.io/biocontainers/samtools:1.10--h9402c20_2"
+        Int timeMinutes = 1 + ceil(size(inputBam, "G") * 2)
+        Int? threads
     }
 
     command {
-        samtools fastq \
-        ~{true="-1" false="-s" defined(outputRead2)} ~{outputRead1} \
-        ~{"-2 " + outputRead2} \
-        ~{"-0 " + outputRead0} \
-        ~{"-f " + includeFilter} \
-        ~{"-F " + excludeFilter} \
-        ~{"-G " + excludeSpecificFilter} \
-        ~{true="-N" false="-n" appendReadNumber} \
-        ~{true="-O" false="" outputQuality} \
-        ~{"-c " + compressionLevel} \
+        set -e
+        mkdir -p "$(dirname ~{outputPath})"
+        samtools sort \
+        -l ~{compressionLevel} \
+        ~{true="-n" false="" sortByName} \
         ~{"--threads " + threads} \
+        -o ~{outputPath} \
         ~{inputBam}
     }
 
     output {
-        File read1 = outputRead1
-        File? read2 = outputRead2
-        File? read0 = outputRead0
+        File outputSortedBam = outputPath
     }
 
     runtime {
-        cpu: threads
+        cpu: 1 + select_first([threads, 0])
         memory: memory
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
         # inputs
-        inputBam: {description: "The bam file to process.", category: "required"}
-        outputRead1: {description: "The location the reads (first reads for pairs, in case of paired-end sequencing) should be written to.", category: "required"}
-        outputRead2: {description: "The location the second reads from pairs should be written to.", category: "common"}
-        outputRead0: {description: "The location the unpaired reads should be written to (in case of paired-end sequenicng).", category: "advanced"}
-        includeFilter: {description: "Include reads with ALL of these flags. Corresponds to `-f`", category: "advanced"}
-        excludeFilter: {description: "Exclude reads with ONE OR MORE of these flags. Corresponds to `-F`", category: "advanced"}
-        excludeSpecificFilter: {description: "Exclude reads with ALL of these flags. Corresponds to `-G`", category: "advanced"}
-        appendReadNumber: {description: "Append /1 and /2 to the read name, or don't. Corresponds to `-n/N`", category: "advanced"}
-        outputQuality: {description: "Equivalent to samtools fastq's `-O` flag.", category: "advanced"}
-        threads: {description: "The number of threads to use.", category: "advanced"}
-        memory: {description: "The amount of memory this job will use.", category: "advanced"}
-        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-                      category: "advanced"}
+        inputBam: {description: "The input SAM file.", category: "required"}
+        outputPath: {description: "Output directory path + output file.", category: "required"}
+        sortByName: {description: "Sort the inputBam by read name instead of position.", category: "advanced"}
+        compressionLevel: {description: "Compression level from 0 (uncompressed) to 9 (best).", category: "advanced"}
+        memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
+        threads: {description: "The number of additional threads that will be used for this task.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        # outputs
+        outputSortedBam: {description: "Sorted BAM file."}
     }
 }
 
@@ -353,6 +418,7 @@ task Tabix {
         File inputFile
         String outputFilePath = "indexed.vcf.gz"
         String type = "vcf"
+        Int timeMinutes = 1 + ceil(size(inputFile, "G") * 2)
         String dockerImage = "quay.io/biocontainers/tabix:0.2.6--ha92aebf_0"
     }
     # FIXME: It is better to do the indexing on VCF creation. Not in a separate task. With file localization this gets hairy fast.
@@ -372,6 +438,7 @@ task Tabix {
     }
 
     runtime {
+        time_minutes: timeMinutes
        docker: dockerImage
     }
 
@@ -381,6 +448,7 @@ task Tabix {
         outputFilePath: {description: "The location where the file should be written to. The index will appear alongside this link to the file.",
                         category: "common"}
         type: {description: "The type of file (eg. vcf or bed) to be indexed.", category: "common"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -399,6 +467,7 @@ task View {
 
         Int threads = 1
         String memory = "1G"
+        Int timeMinutes = 1 + ceil(size(inFile, "G") * 5)
         String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
     }
     String outputIndexPath = basename(outputFileName) + ".bai"
@@ -428,6 +497,7 @@ task View {
     runtime {
         cpu: threads
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -444,41 +514,8 @@ task View {
 
         threads: {description: "The number of threads to use.", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
-}
-
-task FilterShortReadsBam {
-    input {
-        File bamFile
-        String outputPathBam
-        String dockerImage = "quay.io/biocontainers/samtools:1.8--h46bd0b3_5"
-    }
-    
-    String outputPathBamIndex = sub(outputPathBam, "\.bam$", ".bai")
-
-    command {
-        set -e
-        mkdir -p "$(dirname ~{outputPathBam})"
-        samtools view -h ~{bamFile} | \
-        awk 'length($10) > 30 || $1 ~/^@/' | \
-        samtools view -bS -> ~{outputPathBam}
-        samtools index ~{outputPathBam} ~{outputPathBamIndex}
-    }
-
-    output {
-        File filteredBam = outputPathBam
-        File filteredBamIndex = outputPathBamIndex
-    }
-
-    runtime {
-        docker: dockerImage
-    }
-
-    parameter_meta {
-        bamFile: {description: "The bam file to process.", category: "required"}
-        outputPathBam: {description: "The filtered bam file.", category: "common"}
-        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
-    }
-}
+}
\ No newline at end of file
diff --git a/somaticseq.wdl b/somaticseq.wdl
index 49e5c36d4a5b388e596bcd2c943812f8011c3a57..7b9a4403c6e31c1ad6374b4561bfaee96dc4c435 100644
--- a/somaticseq.wdl
+++ b/somaticseq.wdl
@@ -47,6 +47,7 @@ task ParallelPaired {
         File? strelkaIndel
 
         Int threads = 1
+        Int timeMinutes = 60
         String dockerImage = "lethalfang/somaticseq:3.1.0"
     }
 
@@ -89,6 +90,7 @@ task ParallelPaired {
 
     runtime {
         cpu: threads
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -118,6 +120,7 @@ task ParallelPaired {
         strelkaIndel: {description: "An indel VCF as produced by somaticsniper.", category: "advanced"}
 
         threads: {description: "The number of threads to use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -150,6 +153,7 @@ task ParallelPairedTrain {
         File? strelkaIndel
 
         Int threads = 1
+        Int timeMinutes = 240
         String dockerImage = "lethalfang/somaticseq:3.1.0"
     }
 
@@ -191,6 +195,7 @@ task ParallelPairedTrain {
 
     runtime {
         cpu: threads
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -220,6 +225,7 @@ task ParallelPairedTrain {
         strelkaIndel: {description: "An indel VCF as produced by somaticsniper.", category: "advanced"}
 
         threads: {description: "The number of threads to use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -244,6 +250,7 @@ task ParallelSingle {
         File? strelkaVCF
 
         Int threads = 1
+        Int timeMinutes = 60
         String dockerImage = "lethalfang/somaticseq:3.1.0"
     }
 
@@ -279,6 +286,7 @@ task ParallelSingle {
 
     runtime {
         cpu: threads
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -300,6 +308,7 @@ task ParallelSingle {
         strelkaVCF: {description: "A VCF as produced by strelka.", category: "advanced"}
 
         threads: {description: "The number of threads to use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -324,6 +333,7 @@ task ParallelSingleTrain {
         File? strelkaVCF
 
         Int threads = 1
+        Int timeMinutes = 240
         String dockerImage = "lethalfang/somaticseq:3.1.0"
     }
 
@@ -358,6 +368,7 @@ task ParallelSingleTrain {
 
     runtime {
         cpu: threads
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -379,6 +390,7 @@ task ParallelSingleTrain {
         strelkaVCF: {description: "A VCF as produced by strelka.", category: "advanced"}
 
         threads: {description: "The number of threads to use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -389,6 +401,7 @@ task ModifyStrelka {
         File strelkaVCF
         String outputVCFName = basename(strelkaVCF, ".gz")
         String dockerImage = "lethalfang/somaticseq:3.1.0"
+        Int timeMinutes = 20
     }
 
     command {
@@ -407,12 +420,14 @@ task ModifyStrelka {
     }
 
     runtime {
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
         strelkaVCF: {description: "A vcf file as produced by strelka.", category: "required"}
         outputVCFName: {description: "The location the output VCF file should be written to.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/star.wdl b/star.wdl
index 5d0d6b6c2999c53b65bf7c66ed31ac1d5ae7f31b..4942f35e167a4ff14d272b3911e8bd4d68904914 100644
--- a/star.wdl
+++ b/star.wdl
@@ -89,7 +89,7 @@ task GenomeGenerate {
 task Star {
     input {
         Array[File]+ inputR1
-        Array[File]? inputR2
+        Array[File] inputR2 = []
         Array[File]+ indexFiles
         String outFileNamePrefix
         String outSAMtype = "BAM SortedByCoordinate"
@@ -101,7 +101,8 @@ task Star {
         Int? limitBAMsortRAM
 
         Int runThreadN = 4
-        String memory = "48G"
+        String memory = "~{5 + ceil(size(indexFiles, "G"))}G"
+        Int timeMinutes = 1 + ceil(size(flatten([inputR1, inputR2]), "G") * 180 / runThreadN)
         String dockerImage = "quay.io/biocontainers/star:2.7.3a--0"
     }
 
@@ -133,6 +134,7 @@ task Star {
     runtime {
         cpu: runThreadN
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -150,6 +152,7 @@ task Star {
         limitBAMsortRAM: {description: "Equivalent to star's `--limitBAMsortRAM` option.", category: "advanced"}
         runThreadN: {description: "The number of threads to use.", category: "advanced"}
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/strelka.wdl b/strelka.wdl
index 826cbd8e260014c1816d6640c313f3ebbb39bdef..50c38b55ae4374efc7ea32e7be8f6e08a0076cdb 100644
--- a/strelka.wdl
+++ b/strelka.wdl
@@ -36,6 +36,7 @@ task Germline {
 
         Int cores = 1
         Int memoryGb = 4
+        Int timeMinutes = 90
         String dockerImage = "quay.io/biocontainers/strelka:2.9.7--0"
     }
 
@@ -62,6 +63,7 @@ task Germline {
     runtime {
         docker: dockerImage
         cpu: cores
+        time_minutes: timeMinutes
         memory: "~{memoryGb}G"
     }
 
@@ -78,6 +80,7 @@ task Germline {
 
         cores: {description: "The number of cores to use.", category: "advanced"}
         memoryGb: {description: "The amount of memory this job will use in Gigabytes.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -100,6 +103,7 @@ task Somatic {
 
         Int cores = 1
         Int memoryGb = 4
+        Int timeMinutes = 90
         String dockerImage = "quay.io/biocontainers/strelka:2.9.7--0"
 
         File? doNotDefineThis #FIXME
@@ -131,6 +135,7 @@ task Somatic {
     runtime {
         docker: dockerImage
         cpu: cores
+        time_minutes: timeMinutes
         memory: "~{memoryGb}G"
     }
 
@@ -150,6 +155,7 @@ task Somatic {
 
         cores: {description: "The number of cores to use.", category: "advanced"}
         memoryGb: {description: "The amount of memory this job will use in Gigabytes.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/stringtie.wdl b/stringtie.wdl
index cfaccc92f80d1ab9d489e37e31ea2dd3e28c0584..5ed62deadd8758f2b476b3ff02cf79fb9d1a719a 100644
--- a/stringtie.wdl
+++ b/stringtie.wdl
@@ -32,7 +32,8 @@ task Stringtie {
         String? geneAbundanceFile
 
         Int threads = 1
-        String memory = "10G"
+        String memory = "2G"
+        Int timeMinutes = 1 + ceil(size(bam, "G") * 60 / threads)
         String dockerImage = "quay.io/biocontainers/stringtie:1.3.4--py35_0"
     }
 
@@ -58,54 +59,24 @@ task Stringtie {
     runtime {
         cpu: threads
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
-        bam: {
-            description: "The input BAM file.",
-            category: "required"
-        }
-        bamIndex: {
-            description: "The input BAM file's index.",
-            category: "required"
-        }
-        referenceGtf: {
-            description: "A reference GTF file to be used as guide.",
-            category: "common"
-        }
-        skipNovelTranscripts: {
-            description: "Whether new transcripts should be assembled or not.",
-            category: "common"
-        }
-        assembledTranscriptsFile: {
-            description: "Where the output of the assembly should be written.",
-            category: "required"
-        }
-        firstStranded: {
-            description: "Equivalent to the --rf flag of stringtie.",
-            category: "required"
-        }
-        secondStranded: {
-            description: "Equivalent to the --fr flag of stringtie.",
-            category: "required"
-        }
-        geneAbundanceFile: {
-            description: "Where the abundance file should be written.",
-            category: "common"
-        }
-        threads: {
-            description: "The number of threads to use.",
-            category: "advanced"
-        }
-        memory: {
-            description: "The amount of memory needed for this task in GB.",
-            category: "advanced"
-        }
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        bam: {description: "The input BAM file.", category: "required"}
+        bamIndex: {description: "The input BAM file's index.", category: "required"}
+        referenceGtf: {description: "A reference GTF file to be used as guide.", category: "common"}
+        skipNovelTranscripts: {description: "Whether new transcripts should be assembled or not.", category: "common"}
+        assembledTranscriptsFile: {description: "Where the output of the assembly should be written.", category: "required"}
+        firstStranded: {description: "Equivalent to the --rf flag of stringtie.", category: "required"}
+        secondStranded: {description: "Equivalent to the --fr flag of stringtie.", category: "required"}
+        geneAbundanceFile: {description: "Where the abundance file should be written.", category: "common"}
+        threads: {description: "The number of threads to use.", category: "advanced"}
+        memory: {description: "The amount of memory needed for this task in GB.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
 
@@ -123,6 +94,7 @@ task Merge {
         String? label
 
         String memory = "10G"
+        Int timeMinutes = 1 + ceil(size(gtfFiles, "G") * 20)
         String dockerImage = "quay.io/biocontainers/stringtie:1.3.4--py35_0"
     }
 
@@ -148,57 +120,24 @@ task Merge {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
     parameter_meta {
-        gtfFiles: {
-            description: "The GTF files produced by stringtie.",
-            category: "required"
-        }
-        outputGtfPath: {
-            description: "Where the output should be written.",
-            category: "required"
-        }
-        guideGtf: {
-            description: "Equivalent to the -G option of 'stringtie --merge'.",
-            category: "advanced"
-        }
-        minimumLength: {
-            description: "Equivalent to the -m option of 'stringtie --merge'.",
-            category: "advanced"
-        }
-        minimumCoverage: {
-            description: "Equivalent to the -c option of 'stringtie --merge'.",
-            category: "advanced"
-        }
-        minimumFPKM: {
-            description: "Equivalent to the -F option of 'stringtie --merge'.",
-            category: "advanced"
-        }
-        minimumTPM: {
-            description: "Equivalent to the -T option of 'stringtie --merge'.",
-            category: "advanced"
-        }
-        minimumIsoformFraction: {
-            description: "Equivalent to the -f option of 'stringtie --merge'.",
-            category: "advanced"
-        }
-        keepMergedTranscriptsWithRetainedIntrons: {
-            description: "Equivalent to the -i flag of 'stringtie --merge'.",
-            category: "advanced"
-        }
-        label: {
-            description: "Equivalent to the -l option of 'stringtie --merge'.",
-            category: "advanced"
-        }
-        memory: {
-            description: "The amount of memory needed for this task in GB.",
-            category: "advanced"
-        }
-        dockerImage: {
-            description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
-            category: "advanced"
-        }
+        gtfFiles: {description: "The GTF files produced by stringtie.", category: "required"}
+        outputGtfPath: {description: "Where the output should be written.", category: "required"}
+        guideGtf: {description: "Equivalent to the -G option of 'stringtie --merge'.", category: "advanced"}
+        minimumLength: {description: "Equivalent to the -m option of 'stringtie --merge'.", category: "advanced"}
+        minimumCoverage: {description: "Equivalent to the -c option of 'stringtie --merge'.", category: "advanced"}
+        minimumFPKM: {description: "Equivalent to the -F option of 'stringtie --merge'.", category: "advanced"}
+        minimumTPM: {description: "Equivalent to the -T option of 'stringtie --merge'.", category: "advanced"}
+        minimumIsoformFraction: {description: "Equivalent to the -f option of 'stringtie --merge'.", category: "advanced"}
+        keepMergedTranscriptsWithRetainedIntrons: {description: "Equivalent to the -i flag of 'stringtie --merge'.", category: "advanced"}
+        label: {description: "Equivalent to the -l option of 'stringtie --merge'.", category: "advanced"}
+        memory: {description: "The amount of memory needed for this task in GB.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
+        dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
+                      category: "advanced"}
     }
 }
diff --git a/survivor.wdl b/survivor.wdl
index ded11d75a64b9de98312a520d0fd284aa0ecda5c..e5ac7b5bfb3bf8b2a9230f6c65f790287a4bafb8 100644
--- a/survivor.wdl
+++ b/survivor.wdl
@@ -33,6 +33,7 @@ task Merge {
         Int minSize = 30
         String outputPath = "./survivor/merged.vcf"
         String memory = "24G"
+        Int timeMinutes = 60
         String dockerImage = "quay.io/biocontainers/survivor:1.0.6--h6bb024c_0"
     }
 
@@ -57,6 +58,7 @@ task Merge {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -71,6 +73,7 @@ task Merge {
         minSize: {description: "The mimimum size of SV to be merged", category: "advanced"}
         outputPath: {description: "The location the output VCF file should be written.", category: "common"}
         memory: {description: "The memory required to run the programs", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }
diff --git a/talon.wdl b/talon.wdl
index 6ddb841e12a76a99ba2b94f776f91c3315f8de38..b2ae3a622067184bfb6fc5524cdd7b137460d10e 100644
--- a/talon.wdl
+++ b/talon.wdl
@@ -31,6 +31,7 @@ task CreateAbundanceFileFromDatabase {
         File? datasetsFile
 
         String memory = "4G"
+        Int timeMinutes = 30
         String dockerImage = "biocontainers/talon:v4.4.2_cv1"
     }
 
@@ -52,6 +53,7 @@ task CreateAbundanceFileFromDatabase {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -64,6 +66,7 @@ task CreateAbundanceFileFromDatabase {
         whitelistFile: {description: "Whitelist file of transcripts to include in the output.", category: "advanced"}
         datasetsFile: {description: "A file indicating which datasets should be included.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -84,6 +87,7 @@ task CreateGtfFromDatabase {
         File? datasetFile
 
         String memory = "4G"
+        Int timeMinutes = 30
         String dockerImage = "biocontainers/talon:v4.4.2_cv1"
     }
 
@@ -106,6 +110,7 @@ task CreateGtfFromDatabase {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -119,6 +124,7 @@ task CreateGtfFromDatabase {
         whitelistFile: {description: "Whitelist file of transcripts to include in the output.", category: "advanced"}
         datasetFile: {description: "A file indicating which datasets should be included.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -135,6 +141,7 @@ task FilterTalonTranscripts {
         File? pairingsFile
 
         String memory = "4G"
+        Int timeMinutes = 30
         String dockerImage = "biocontainers/talon:v4.4.2_cv1"
     }
 
@@ -154,6 +161,7 @@ task FilterTalonTranscripts {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -164,6 +172,7 @@ task FilterTalonTranscripts {
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         pairingsFile: {description: "A file indicating which datasets should be considered together.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -180,6 +189,7 @@ task GetReadAnnotations {
         File? datasetFile
 
         String memory = "4G"
+        Int timeMinutes = 30
         String dockerImage = "biocontainers/talon:v4.4.2_cv1"
     }
 
@@ -199,6 +209,7 @@ task GetReadAnnotations {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -209,6 +220,7 @@ task GetReadAnnotations {
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         datasetFile: {description: "A file indicating which datasets should be included.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -228,6 +240,7 @@ task InitializeTalonDatabase {
         String outputPrefix
 
         String memory = "10G"
+        Int timeMinutes = 60
         String dockerImage = "biocontainers/talon:v4.4.2_cv1"
     }
 
@@ -251,6 +264,7 @@ task InitializeTalonDatabase {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -265,6 +279,7 @@ task InitializeTalonDatabase {
         cutoff3p: {description: "Maximum allowable distance (bp) at the 3' end during annotation.", category: "advanced"}
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -277,6 +292,7 @@ task ReformatGtf {
         File GTFfile
 
         String memory = "4G"
+        Int timeMinutes = 30
         String dockerImage = "biocontainers/talon:v4.4.2_cv1"
     }
 
@@ -292,6 +308,7 @@ task ReformatGtf {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -299,6 +316,7 @@ task ReformatGtf {
         # inputs
         GTFfile: {description: "GTF annotation containing genes, transcripts, and edges.", category: "required"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -315,6 +333,7 @@ task SummarizeDatasets {
         File? datasetGroupsCSV
 
         String memory = "4G"
+        Int timeMinutes = 50
         String dockerImage = "biocontainers/talon:v4.4.2_cv1"
     }
 
@@ -334,6 +353,7 @@ task SummarizeDatasets {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -344,6 +364,7 @@ task SummarizeDatasets {
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         datasetGroupsCSV: {description: "File of comma-delimited dataset groups to process together.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
@@ -364,6 +385,7 @@ task Talon {
 
         Int cores = 4
         String memory = "25G"
+        Int timeMinutes = 2880
         String dockerImage = "biocontainers/talon:v4.4.2_cv1"
     }
 
@@ -399,6 +421,7 @@ task Talon {
     runtime {
         cpu: cores
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -414,6 +437,7 @@ task Talon {
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         cores: {description: "The number of cores to be used.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
 
         # outputs
diff --git a/transcriptclean.wdl b/transcriptclean.wdl
index 68bcbf240ca1f5845c0848ca07b477986794b611..15da1f583ee7c0271e3e54751d2c588cbba5087d 100644
--- a/transcriptclean.wdl
+++ b/transcriptclean.wdl
@@ -28,6 +28,7 @@ task GetSJsFromGtf {
         Int minIntronSize = 21
 
         String memory = "8G"
+        Int timeMinutes = 30
         String dockerImage = "biocontainers/transcriptclean:v2.0.2_cv1"
     }
 
@@ -47,6 +48,7 @@ task GetSJsFromGtf {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -57,6 +59,7 @@ task GetSJsFromGtf {
         minIntronSize: {description: "Minimum size of intron to consider a junction.", category: "advanced"}
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
         # outputs
@@ -70,6 +73,7 @@ task GetTranscriptCleanStats {
         String outputPrefix
 
         String memory = "4G"
+        Int timeMinutes = 30
         String dockerImage = "biocontainers/transcriptclean:v2.0.2_cv1"
     }
 
@@ -87,6 +91,7 @@ task GetTranscriptCleanStats {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -95,6 +100,7 @@ task GetTranscriptCleanStats {
         transcriptCleanSAMfile: {description: "Output SAM file from TranscriptClean", category: "required"}
         outputPrefix: {description: "Output directory path + output file prefix.", category: "required"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
 
@@ -124,6 +130,7 @@ task TranscriptClean {
 
         Int cores = 1
         String memory = "25G"
+        Int timeMinutes = 2880
         String dockerImage = "biocontainers/transcriptclean:v2.0.2_cv1"
     }
 
@@ -159,6 +166,7 @@ task TranscriptClean {
     runtime {
         cpu: cores
         memory: memory
+        time_minute: timeMinutes
         docker: dockerImage
     }
 
@@ -181,6 +189,7 @@ task TranscriptClean {
         variantFile: {description: "VCF formatted file of variants.", category: "common"}
         cores: {description: "The number of cores to be used.", category: "advanced"}
         memory: {description: "The amount of memory available to the job.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
         
diff --git a/umi-tools.wdl b/umi-tools.wdl
index 07518e57e5954077f643645d5f43ad03f09611ea..c5f3b145c50c30465652c29c96523a0b4687bf81 100644
--- a/umi-tools.wdl
+++ b/umi-tools.wdl
@@ -29,7 +29,7 @@ task Extract {
         Boolean threePrime = false
         String read1Output = "umi_extracted_R1.fastq.gz"
         String? read2Output = "umi_extracted_R2.fastq.gz"
-
+        Int timeMinutes = 1 + ceil(size([read1, read2], "G") * 2)
         String dockerImage = "quay.io/biocontainers/mulled-v2-509311a44630c01d9cb7d2ac5727725f51ea43af:6089936aca6219b5bb5f54210ac5eb456c7503f2-0"
     }
 
@@ -51,6 +51,7 @@ task Extract {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
     }
 
     parameter_meta {
@@ -61,6 +62,7 @@ task Extract {
         threePrime: {description: "Whether or not the UMI's are at the reads' 3' end. If false the UMIs are extracted from the 5' end.", category: "advanced"}
         read1Output: {description: "The location to write the first/single-end output fastq file to.", category: "advanced"}
         read2Output: {description: "The location to write the second-end output fastq file to.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
@@ -75,7 +77,8 @@ task Dedup {
         String? statsPrefix
         Boolean paired = true
 
-        String memory = "5G"
+        String memory = "25G"
+        Int timeMinutes = 30 + ceil(size(inputBam, "G") * 30)
 
         # Use a multi-package-container which includes umi_tools (0.5.5) and samtools (1.9)
         String dockerImage = "quay.io/biocontainers/mulled-v2-509311a44630c01d9cb7d2ac5727725f51ea43af:6089936aca6219b5bb5f54210ac5eb456c7503f2-0"
@@ -105,6 +108,7 @@ task Dedup {
 
     runtime {
         docker: dockerImage
+        time_minutes: timeMinutes
         memory: memory
     }
 
@@ -116,6 +120,7 @@ task Dedup {
         umiSeparator: {description: "Seperator used for UMIs in the read names.", category: "advanced"}
         paired: {description: "Whether or not the data is paired.", category: "common"}
         memory: {description: "The amount of memory required for the task.", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/vardict.wdl b/vardict.wdl
index 7bfd118ee99f67da1af482b240d1f9c6d34fe9f1..92beb32e91ec14baf170183b9bdc283f83850595 100644
--- a/vardict.wdl
+++ b/vardict.wdl
@@ -48,14 +48,15 @@ task VarDict {
         Float minimumAlleleFrequency = 0.02
 
         Int threads = 1
-        String memory = "40G"
+        String memory = "18G"
         String javaXmx = "16G"
+        Int timeMinutes = 300
         String dockerImage = "quay.io/biocontainers/vardict-java:1.5.8--1"
     }
 
     command {
         set -e -o pipefail
-        export JAVA_OPTS="-Xmx~{javaXmx}"
+        export JAVA_OPTS="-Xmx~{javaXmx} -XX:ParallelGCThreads=1"
         vardict-java \
         ~{"-th " + threads} \
         -G ~{referenceFasta} \
@@ -87,6 +88,7 @@ task VarDict {
     runtime {
         cpu: threads + 2
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -116,6 +118,7 @@ task VarDict {
         memory: {description: "The amount of memory this job will use.", category: "advanced"}
         javaXmx: {description: "The maximum memory available to the program. Should be lower than `memory` to accommodate JVM overhead.",
                   category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.",
                       category: "advanced"}
     }
diff --git a/vt.wdl b/vt.wdl
index 54599db01b78b900c172516993d3e6399f036f6b..d4c134b98ffa2e0e30910a4c1241b1e11df467f8 100644
--- a/vt.wdl
+++ b/vt.wdl
@@ -29,6 +29,7 @@ task Normalize {
         String outputPath = "./vt/normalized_decomposed.vcf"
         String dockerImage = "quay.io/biocontainers/vt:0.57721--hdf88d34_2"
         String memory = "4G"
+        Int timeMinutes = 30
     }
 
     command {
@@ -43,6 +44,7 @@ task Normalize {
 
     runtime {
         memory: memory
+        time_minutes: timeMinutes
         docker: dockerImage
     }
 
@@ -54,6 +56,7 @@ task Normalize {
         referenceFasta: {description: "The reference fasta file which was also used for mapping.", category: "required"}
         referenceFastaFai: {description: "The index for the reference fasta file.", category: "required"}
         memory: {description: "The memory required to run the programs", category: "advanced"}
+        timeMinutes: {description: "The maximum amount of time the job will run in minutes.", category: "advanced"}
         dockerImage: {description: "The docker image used for this task. Changing this may result in errors which the developers may choose not to address.", category: "advanced"}
     }
 }