Sst Batch Jobs

June 21, 2025

The simplest way to run container batch jobs on AWS with SST Task + Cron ✍️

One file, one Docker image, and a single command (sst deploy) — that’s all it takes to have a repeat‑able batch workload running every night in London.

This guide follows the same structure and terse style as my Google Sign‑in with Next.js post. We will

  1. scaffold an SST app
  2. add a tiny Python job
  3. wire it up with sst.aws.Task
  4. schedule it with sst.aws.Cron (optional)
  5. run it locally in dev mode
  6. ship it to prod on Fargate

The finished repo is tomdekan/sst-task-starter (swap the name if you publish under something else).


0  Prerequisites (≈5 min)

WhatCommand / note
Node ≥ 18 & npm ≥ 9nvm install 18 && nvm use 18
SST CLInpm install -g sst
AWS credsaws configure (pick eu‑west‑2 for London)
DockerDesktop or CLI

1  Scaffold the project

npx create-sst@latest batch-starter
cd batch-starter

2  Add the job

batch-starter/
├─ jobs/
│  └─ resize/
│     ├─ Dockerfile
│     └─ main.py
└─ sst.config.ts

jobs/resize/Dockerfile

FROM public.ecr.aws/python/python:3.12-slim
COPY main.py /app/
WORKDIR /app
ENTRYPOINT ["python", "main.py"]

jobs/resize/main.py

import uuid, time
job_id = uuid.uuid4()
print(f"🏃 Running job {job_id}")
time.sleep(5)            # pretend work
print("✅ Job finished")

Swap in your real workload when ready.


3  Wire up Task (and optional Cron)

Edit sst.config.ts:

import * as sst from 'sst'
 
export default function App() {
  // one‑line Fargate task
  const resize = new sst.aws.Task('ResizeJob', {
    image: { context: './jobs/resize' },
    cpu: 1,
    memory: 1024,
    dev: { command: 'python main.py' }, // instant local loop
  })
 
  // optional nightly run at 01:00 London (00:00 UTC)
  new sst.aws.Cron('NightlyRun', {
    task: resize,
    schedule: 'cron(0 0 * * ? *)',
  })
}
  • Task spins up a container on AWS Fargate.
  • Cron fires it through EventBridge on schedule.

4  Run it locally (fast feedback)

sst dev

sst dev launches a terminal multiplexer that

  • hot‑reloads infra changes,
  • proxies the task to your laptop via dev.command, and
  • prints the 🏃 / ✅ logs instantly.

Iterate without building/pushing images.


5  Deploy to prod (eu‑west‑2, London)

sst deploy --stage prod --region eu-west-2

SST will

  1. build the Docker image and push to ECR,
  2. create an ECS cluster + task definition,
  3. set up CloudWatch Logs, and
  4. (if you kept Cron) create an EventBridge rule.

Total wait: ~2 minutes.


6  Kick it off on demand

Anywhere in your AWS account:

import { Resource } from 'sst'
import { task } from 'sst/aws/task'
 
await task.run(Resource.ResizeJob, { SRC: 's3://bucket/foo.png' })

Returns a task ID; logs land under /sst/ResizeJob/* in CloudWatch.


7  Monitor & troubleshoot

NeedWhere to look
Task status / exit codeECS → Clusters → Tasks
Container logsCloudWatch Logs /sst/ResizeJob/*
Cron trigger historyEventBridge → Rules → NightlyRun

AnalogyTask is a washing machine. You load clothes (input), hit Start, go for tea, and Fargate handles the water, power, and spin cycle. No servers to babysit.


8  Clean up (when you’re done)

sst remove --stage prod --region eu-west-2

When Task + Cron is enough — and when it isn’t

Use‑caseStick with Task?
≤ 4 vCPU, ≤ 30 GB RAM, no GPUYes
Nightly ETL, image resize, PDF mergeYes
GPU workloads, 10 k‑node sweeps, Spot fleetsSwitch to AWS Batch
Millisecond‑scale jobsLambda is cheaper

Sources


Happy shipping!

Want to ship better features with AI?
Join my free weekly newsletter.

No spam guaranteed Unsubscribe whenever