Some workloads are neither services nor streams: render ten thousand frames, run the Monte Carlo risk sweep, process the nightly genomics batch, simulate the part. The shape is embarrassingly parallel tasks against a pool of machines, and Azure Batch is the managed scheduler for exactly that shape, with the classic HPC stack the alternative when the shape is tightly coupled instead.
The Batch Model
Three nouns: pools of compute nodes (VM size, image or container configuration, your VNet per the networking invariants), jobs as task containers, and tasks as the unit of work, a command line with input files pulled from storage and outputs pushed back. Batch schedules tasks onto nodes, retries failures per your policy, and runs dependency graphs when tasks declare prerequisites, which covers the reduce step after the map without external orchestration. Container tasks are the modern default, the image from your ACR carries the environment and the node image stops mattering, and for data movement the ADLS Gen2 patterns from the storage post are the input output substrate, with task working storage on the node’s local NVMe for the hot path.
// autoscale formula: chase the queue, prefer spot, cap the spend
pendingTasks = max($PendingTasks.GetSample(TimeInterval_Minute * 5));
targetVMs = min(200, pendingTasks / 4);
$TargetLowPriorityNodes = targetVMs;
$TargetDedicatedNodes = min(10, targetVMs * 0.1);
$NodeDeallocationOption = taskcompletion;
That formula is the economics of the service in five lines: scale follows the queue, spot (low priority) nodes carry ninety percent of the fleet at their steep discount because batch tasks are the perfect eviction tolerant workload, a small dedicated floor keeps progress guaranteed, and nodes drain on task completion rather than mid work. The FinOps posts meet their ideal customer here, batch compute is where spot stops being a tactic and becomes the architecture.
Designing Tasks That Scale
The craft is task granularity and idempotency. Tasks too small drown in scheduling overhead; too large lose too much work per eviction, and the sweet spot for spot heavy pools is minutes to a small number of hours per task with checkpointing for anything longer. Idempotency is mandatory because retries and evictions guarantee reruns: outputs written to deterministic paths with atomic finalization, or keyed upserts, the same discipline the messaging posts demanded. Package per node setup in start tasks or the container image, never in per task installs, and pull secrets through the pool’s managed identity from Key Vault rather than baking credentials into task command lines, which end up in logs. Monitor the three numbers that describe a batch system: queue depth, task failure rate by exit code, and pool utilization, with the idle node alarm being the cost bug detector, a pool that stays warm after the queue empties is the space heater the Databricks post warned about.
When It Is Real HPC Instead
Batch assumes tasks that do not talk to each other. When they do, MPI codes, CFD, weather, molecular dynamics, the game changes to tightly coupled: InfiniBand equipped HB and HX series VMs, placement groups for latency, and usually a traditional scheduler because the users and their scripts expect one. Azure CycleCloud provisions and autoscales that world, Slurm or PBS clusters materialized on demand, scaling with the queue, wired to the NetApp Files or managed Lustre storage tier the IO profile demands (a storage conversation continuing later this week). The decision line: independent tasks at any scale, Batch; MPI and a user community fluent in sbatch, CycleCloud with Slurm; and both share the estate’s invariants, VNets, identities, policy, cost tags, because a hundred thousand cores on discount is still governed compute in this series.
Cheers
Osama
Leave a Reply