What Is AWS Batch? Jobs, Queues, Fargate vs EC2, and Use Cases

AWS Batch is a fully managed service for running batch computing jobs on AWS. You package your processing logic in a container, submit it to a job queue, and AWS Batch handles provisioning compute, running the job, and releasing resources when it finishes. There is no 15-minute time limit, no idle fleet to pay for between runs, and no server configuration to maintain.

Use AWS Batch when your jobs are too long for Lambda, too compute-heavy for a single instance, or when you need to run dozens or hundreds of tasks in parallel. Do not use it for immediate user-facing requests, continuously-running services, or short tasks where Lambda is simpler and cheaper.

AWS Batch in simple terms

Most cloud compute services wait for requests and respond to them. AWS Batch is different. You give it a workload (a list of files to transform, a dataset to process, a simulation to run) and it works through the jobs and stops when finished.

Analogy

Batch is like a factory shift. When the shift starts, workers arrive, process everything on the production line, and leave when the work is done. You do not keep the factory running overnight waiting for the next job. You fire it up when there is work, and shut it down when there is not.

The difference from a simple cron script is scale and reliability. AWS Batch can run one job or hundreds in parallel, across Fargate, EC2, or an EKS cluster. It handles automatic retries if a job fails, dependency chains if jobs must run in order, and queue priority when multiple jobs compete for resources. You define what to run; Batch handles the infrastructure.

How AWS Batch works

Every AWS Batch job follows this lifecycle:

  1. Define the job. You create a job definition: the container image to run (from Amazon ECR or Docker Hub), the command, CPU and memory requirements, the IAM job role, retry strategy, and any parameters.
  2. Submit to a queue. You submit jobs to a named job queue. Jobs wait there until compute capacity is available. Queue priority controls which jobs get resources first when demand is high.
  3. AWS Batch schedules it. The Batch scheduler picks up queued jobs and assigns them to a compute environment based on queue-to-environment mappings and available capacity.
  4. Compute is provisioned. For managed environments, Batch launches Fargate tasks or EC2 instances automatically. For EKS environments, it schedules pods on your existing cluster nodes.
  5. The container runs. Your job executes to completion. Logs stream to CloudWatch Logs in real time.
  6. Job finishes, retries, or unblocks dependents. On success, any jobs that depended on this one are released. On failure, Batch retries up to the configured attempt limit. After all retry attempts are exhausted, the job is marked FAILED.
Note

Managed compute environments scale to zero when there is no work and scale up when jobs are queued. You pay only for the compute that actually ran.

Core components

Job definition

A job definition is the template for a job. It specifies the container image, the command, memory and CPU requirements, the IAM job role, environment variables, and the retry strategy. Job definitions are versioned. Updating a definition does not affect jobs already in the queue.

Job queue

Jobs are submitted to a queue. The queue holds them until compute is available. You can have multiple queues: a high-priority queue for time-sensitive jobs and a low-priority queue for background work. When resources are limited, Batch schedules the higher-priority queue first.

Compute environment

A compute environment is the pool of resources that runs your jobs. Managed environments handle capacity automatically: Batch launches Fargate tasks or EC2 instances when jobs are queued and scales down when they complete. You configure the maximum vCPU count, the instance types (for EC2), and whether to use on-demand or Spot capacity.

Parameters, retries, and dependencies

Parameters let you reuse one job definition with different inputs. Use Ref::name syntax as placeholders in the command or environment fields and supply the real values at submit time.

Retries are configured per job definition. You set the number of attempts and can add evaluateOnExit conditions: retry on Spot interruption but abort on application errors, for example. This keeps your retry logic explicit and version-controlled rather than buried in application code.

Dependencies let you chain jobs. When submitting job B, specify dependsOn: [jobIdOfA] and Batch will only start B after A completes successfully. This replaces ad-hoc polling code with proper dependency management.

The component relationship: Job → submitted to → Job queue → scheduled onto → Compute environment

Compute choices: Fargate vs EC2 vs EKS

AWS Batch supports three compute environment types. Fargate is the right default for most jobs. EC2 is needed for GPUs and large memory. EKS is useful when your organisation already runs Kubernetes.

Tip

Start with Fargate. It covers the vast majority of batch workloads with minimal configuration. Switch to EC2 only when you hit a specific requirement Fargate cannot meet: GPU support, a custom AMI, or memory beyond what Fargate tasks support.

FeatureFargateEC2EKS
Setup and ops burdenMinimal (no instance management)Low: choose instance types, AWS manages the fleetHigher: requires a running EKS cluster
Startup speedSeconds to minutesSlightly slower (EC2 boot and bootstrap)Fast if nodes already running; slower when autoscaling from zero
GPU supportNoYes (p3, g4dn, p4d instance families)Yes (with GPU node groups)
Custom AMI / imageNoYes, bring your own AMIYes, configure your own node image
Spot / cost savingsYes (Fargate Spot)Yes (EC2 Spot, up to ~90% off on-demand)Yes (Spot node groups)
Memory ceilingUp to 120 GB per taskDepends on instance type, up to several TBDepends on node instance type
Cost trade-offsPay per vCPU/memory second; no idle costOn-demand or Spot; best economics at scale with SpotReuse existing cluster; no separate fleet cost
Best-fit workloadsETL, reports, file transforms, ML preprocessingGPU training, HPC, large memory, custom OS requirementsTeams already on Kubernetes wanting Batch scheduling

Use Amazon EKS compute environments when your team already runs Kubernetes and wants batch jobs scheduled through Batch without managing a second compute fleet.

When to use AWS Batch

Batch is the right choice for jobs that:

  • run longer than Lambda’s timeout allows
  • need more CPU or memory than Lambda supports
  • benefit from running many tasks in parallel
  • can tolerate a few seconds or minutes of startup delay

Common use cases:

  • ETL and data processing. Extract records from a source, transform them, and load into S3 or a data warehouse. See Designing Data Pipelines in AWS for the broader pattern.
  • Report generation. Pull data, compute summaries, and write output files overnight or on a schedule.
  • File transformation. Convert formats, resize images, run OCR, or transcode video across many files in parallel.
  • Scientific simulations. Genomics pipelines, Monte Carlo simulations, and climate models that run for hours or days.
  • ML preprocessing. Clean and transform training datasets before a model training job.
  • Large parallel compute. Split a large workload into hundreds of independent tasks that run at the same time.
  • Scheduled back-office jobs. End-of-day reconciliation, archive creation, and data cleanup that runs nightly.

When not to use AWS Batch

Warning

The most common Batch mistake is using it for requests a user is actively waiting on. Batch jobs take seconds to minutes to start. If a response needs to arrive quickly, use Lambda or a running ECS service.

  • Short tasks under a few minutes. If your job fits within Lambda’s limits, Lambda is simpler and cheaper. Batch is overhead you do not need for quick tasks.
  • Continuously running services. Batch is designed for finite jobs that run to completion, not persistent services. Use ECS or EKS for long-lived, always-on workloads.
  • Orchestration and state machine problems. If your problem is coordinating multiple steps, conditional branching, and error recovery across services, use AWS Step Functions instead.
  • Event-driven microservices. If your compute needs to react to individual events (an S3 upload, an SQS message, an API call), Lambda or ECS with EventBridge is the right model.

AWS Batch vs other AWS options

AWS Batch vs Lambda

Lambda is for short, event-driven functions. It has a 15-minute maximum timeout and a 10 GB memory limit. Batch has no time limit, supports GPU instances, and can run at whatever memory size your EC2 or Fargate task supports.

Analogy

Lambda is a sprinter: fast off the blocks, best for short bursts. Batch is a long-distance runner: it takes a moment to warm up, but there is no finish line it cannot reach.

Use Lambda for event reactions (an S3 upload triggers a resize function). Use Batch for heavy compute jobs that would hit Lambda’s limits or when you need to run many tasks in parallel.

AWS Batch vs Step Functions

Step Functions orchestrates services into multi-step workflows: state, branching, retries, coordination. Batch runs individual jobs. They are complementary. A Step Functions workflow can submit a Batch job as one step in a larger pipeline.

Use Step Functions when the problem is coordination. Use Batch when the problem is compute.

AWS Batch vs ECS/EKS

ECS and EKS run containers for long-lived services: APIs, microservices, and background workers that poll a queue indefinitely. Batch is for finite jobs that run to completion. ECS and EKS do not manage job scheduling, retry logic, or dependency chains the way Batch does.

If you find yourself building a queue-poller service on ECS just to run batch-style jobs, Batch is probably the better tool. See Choosing Between EC2, Lambda, and Containers for the full compute decision framework.

Common mistakes

  1. Using Batch for near-real-time work. Batch jobs take seconds to minutes to start. If a user is waiting for a response, use Lambda or a running ECS service. Batch is for background and scheduled work, not interactive workloads.

  2. Bad resource sizing. Over-provisioning wastes money; under-provisioning causes out-of-memory failures. Profile your job locally to understand its actual CPU and memory usage, then set those values in the job definition with a small buffer.

  3. Ignoring retries and checkpointing for Spot jobs. If you use Spot capacity, your job can be interrupted mid-run. Without a retry strategy in the job definition, a single interruption fails the job permanently. For long jobs, write progress to S3 at regular intervals so a restarted attempt resumes from where it left off rather than from scratch.

  4. Over-permissive IAM job roles. The job role gives your container access to AWS services. Follow the principle of least privilege and grant access only to the specific S3 buckets, DynamoDB tables, or other resources the job actually needs.

  5. No alerting on job failures. A failed job that nobody notices means data is not processed, and the problem may compound across multiple runs. Set up CloudWatch alarms or EventBridge rules to notify your team when batch jobs fail or run significantly longer than expected.

  6. Assuming Spot is safe without resilient job logic. Spot handles the instance interruption and requeues the job. But if your application writes partial results to a database without checkpointing, retrying from the start will cause duplicate writes. Batch retries and idempotent job logic both need to be in place.

A clean example: processing S3 files with Fargate

This example shows a complete data processing job on Fargate. The job downloads a CSV from S3, processes it, and uploads the result. Parameters are mapped to environment variables so you can reuse the same job definition for different inputs.

1. Create a compute environment

aws batch create-compute-environment \
  --compute-environment-name my-fargate-env \
  --type MANAGED \
  --state ENABLED \
  --compute-resources '{
    "type": "FARGATE_SPOT",
    "maxvCpus": 256,
    "subnets": ["subnet-abc123", "subnet-def456"],
    "securityGroupIds": ["sg-batch-jobs"]
  }' \
  --service-role arn:aws:iam::ACCOUNT_ID:role/AWSBatchServiceRole

2. Create a job queue

aws batch create-job-queue \
  --job-queue-name my-job-queue \
  --state ENABLED \
  --priority 100 \
  --compute-environment-order '[{
    "order": 1,
    "computeEnvironment": "my-fargate-env"
  }]'

3. Register a job definition

Parameters use Ref::name as placeholders. Here they are mapped to environment variables so the Python script can read them with os.environ. Supply the real values at submit time.

aws batch register-job-definition \
  --job-definition-name my-data-processor \
  --type container \
  --platform-capabilities FARGATE \
  --container-properties '{
    "image": "ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/data-processor:latest",
    "command": ["python", "process.py"],
    "environment": [
      {"name": "INPUT_FILE",    "value": "Ref::input_file"},
      {"name": "OUTPUT_BUCKET", "value": "Ref::output_bucket"}
    ],
    "resourceRequirements": [
      {"type": "VCPU",   "value": "2"},
      {"type": "MEMORY", "value": "4096"}
    ],
    "jobRoleArn":       "arn:aws:iam::ACCOUNT_ID:role/BatchJobRole",
    "executionRoleArn": "arn:aws:iam::ACCOUNT_ID:role/BatchExecutionRole",
    "networkConfiguration": {"assignPublicIp": "ENABLED"},
    "fargatePlatformConfiguration": {"platformVersion": "LATEST"}
  }' \
  --retry-strategy '{"attempts": 3, "evaluateOnExit": [{"onReason": "Host EC2*", "action": "RETRY"}]}' \
  --parameters '{"input_file": "s3://my-input/default.csv", "output_bucket": "my-output"}'

4. Submit a job

aws batch submit-job \
  --job-name process-dataset-001 \
  --job-queue my-job-queue \
  --job-definition my-data-processor \
  --parameters '{"input_file": "s3://my-input/dataset-001.csv", "output_bucket": "my-output"}'

5. The container code

FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY process.py .

CMD ["python", "process.py"]
# process.py
import os
import json
import boto3

def parse_s3_uri(uri):
    path = uri.replace("s3://", "")
    bucket, _, key = path.partition("/")
    return bucket, key

def process_data(input_path):
    # Replace with your processing logic
    with open(input_path) as f:
        rows = f.readlines()
    return {"rows_processed": len(rows)}

def main():
    input_file    = os.environ["INPUT_FILE"]    # e.g. s3://my-input/dataset-001.csv
    output_bucket = os.environ["OUTPUT_BUCKET"] # e.g. my-output

    s3 = boto3.client("s3")

    # Download input from S3
    src_bucket, src_key = parse_s3_uri(input_file)
    s3.download_file(src_bucket, src_key, "/tmp/input.csv")

    # Process
    results = process_data("/tmp/input.csv")

    # Upload results
    output_key = f"results/{src_key}.json"
    s3.put_object(
        Bucket=output_bucket,
        Key=output_key,
        Body=json.dumps(results),
    )
    print(f"Done: {input_file} -> s3://{output_bucket}/{output_key}")

if __name__ == "__main__":
    main()

6. Monitor the job

# Check job status by ID
aws batch describe-jobs --jobs JOB_ID

# List running jobs in the queue
aws batch list-jobs \
  --job-queue my-job-queue \
  --job-status RUNNING

Logs appear in CloudWatch Logs under the log group configured in your job definition. The job role (BatchJobRole) needs read access to the input S3 bucket and write access to the output bucket.

Frequently asked questions

What is AWS Batch?

AWS Batch is a fully managed service for running batch computing workloads on AWS. You define your job as a container image, submit it to a job queue, and AWS Batch provisions the right compute, runs the job, and cleans up when it finishes. There is no server to manage and no 15-minute time limit.

When should I use AWS Batch instead of Lambda?

Use AWS Batch when your job runs longer than 15 minutes, needs more than 10 GB of memory, or requires GPU resources. Lambda is the right tool for short, event-driven functions. Batch is the right tool for long-running, compute-heavy jobs: data processing, file transformations, ML preprocessing, and scientific simulations.

Can AWS Batch run on Spot or Fargate Spot?

Yes. EC2 compute environments support Spot instances and Fargate compute environments support Fargate Spot. Both reduce costs significantly versus on-demand pricing. AWS Batch handles interruptions automatically. A job interrupted by Spot is marked FAILED and retried on a new instance according to the retry strategy in the job definition.

Can AWS Batch run on Amazon EKS?

Yes. AWS Batch supports Amazon EKS compute environments, allowing you to submit batch jobs through the standard Batch job queue and scheduling system while the jobs run on Kubernetes nodes in your EKS cluster. This is useful when your organisation already manages an EKS cluster and does not want a separate EC2 fleet for batch work.

How do retries and job dependencies work?

Retries are configured in the job definition using a retry strategy. You set the number of attempts and can add evaluateOnExit conditions: retry on Spot interruption but abort on application errors, for example. Job dependencies let you control execution order: when submitting job B, set dependsOn to the job ID of A and Batch will only start B after A completes successfully.

Last verified: 1 April 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.