Sst Batch Jobs
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
- scaffold an SST app
- add a tiny Python job
- wire it up with
sst.aws.Task
- schedule it with
sst.aws.Cron
(optional) - run it locally in dev mode
- 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)
What | Command / note |
---|---|
Node ≥ 18 & npm ≥ 9 | nvm install 18 && nvm use 18 |
SST CLI | npm install -g sst |
AWS creds | aws configure (pick eu‑west‑2 for London) |
Docker | Desktop 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
- build the Docker image and push to ECR,
- create an ECS cluster + task definition,
- set up CloudWatch Logs, and
- (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
Need | Where to look |
---|---|
Task status / exit code | ECS → Clusters → Tasks |
Container logs | CloudWatch Logs /sst/ResizeJob/* |
Cron trigger history | EventBridge → Rules → NightlyRun |
Analogy:
Task
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‑case | Stick with Task? |
---|---|
≤ 4 vCPU, ≤ 30 GB RAM, no GPU | Yes |
Nightly ETL, image resize, PDF merge | Yes |
GPU workloads, 10 k‑node sweeps, Spot fleets | Switch to AWS Batch |
Millisecond‑scale jobs | Lambda is cheaper |
Sources
- Task component docs – https://sst.dev/docs/component/aws/task/
- Cron construct docs – https://docs.sst.dev/cron-jobs
- SST dev mode – https://sst.dev/docs/
- EventBridge cron syntax – https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html
Happy shipping!