Functions seemed like the obvious choice.
Until we hit the constraints that Container App Jobs do not have.
Functions Work Until They Do Not
We started with Azure Functions for our batch workloads.
The model is simple:
- write code
- deploy it
- trigger it on a schedule or event
It worked well for small jobs.
Then we needed longer execution times. Functions have limits.
We needed custom dependencies. The runtime felt restrictive.
We needed to run the same workload locally and in Azure. Functions required different setups.
Container App Jobs Solved What Functions Could Not
Container App Jobs gave us what we actually needed:
- arbitrary execution time
- full control over the container image
- same image runs locally and in production
- no runtime version constraints
- better resource allocation control
We could use whatever libraries we wanted.
We could test the exact same container locally before deploying.
We could run jobs that took hours, not minutes.
The Trade-off Was Worth It
Functions are easier to start with.
They have better integration with Azure services out of the box.
They have lower cold start times for small workloads.
But we traded those conveniences for flexibility.
Container App Jobs require you to think about containers. About images. About startup time.
That overhead paid off when we needed to:
- migrate a job from one language to another
- run a vendor tool that only worked in a specific environment
- debug locally with the exact production environment
- scale a job beyond function limits
When Functions Still Make Sense
We still use Functions.
For lightweight event-driven workloads. For HTTP APIs with simple logic. For quick integrations.
Functions excel when:
- execution time is under 10 minutes
- the runtime supports your needs
- you want fast iteration without containers
- cold start time matters
We use both.
But for our batch workloads, scheduled jobs, and anything that needs control over the environment, Container App Jobs won.
What We Learned
The abstraction is not always better.
Functions abstract away containers, orchestration, and infrastructure.
That abstraction works until it does not.
When you hit the limits, you need more control.
Container App Jobs gave us that control without forcing us into VMs or Kubernetes clusters.
It is still serverless. You still pay per execution. You still get automatic scaling.
But you get to decide what runs, how it runs, and for how long.
For our use case, that made all the difference.
We stopped fighting the platform. We started using the tool that matched our workload.
That is what good platform decisions look like.