How to Deploy an AI Agent to the Cloud

Contents
You built an agent. It is a loop: call a model, read the tool calls it comes back with, run them, feed the results in, go again until the work is done. It runs on your laptop, it works, and it stops the moment you close the lid.
Getting it running around the clock is a different problem from getting it working. Not a harder one, but a different one, and most of the guides on deploying an AI agent skip straight to the deploy command without saying what an agent actually needs from the infrastructure underneath it. That part is worth ten minutes.
What an agent needs that an app does not
Start with the shape of the thing. A web app receives a request, does some work, returns a response, and forgets everything. An agent is the opposite: it is a process that stays alive, accumulates context, and decides for itself what to do next. Four consequences fall out of that.
State has to outlive the process. Conversation history, task progress, what the agent has already tried. If that lives in a Python dict, the next restart is an amnesiac. Put it in a database from the start, keyed by session or task, and write to it at the end of every loop iteration rather than at the end of the run.
Secrets have to come from the environment. Your model provider key, your database URL, whatever credentials the tools need. These belong in environment variables set at deploy time, not baked into the image and definitely not in the repository. Rotating a key should be a redeploy, not a rebuild.
Restarts are normal, so make them boring. Processes get killed. A node reboots, a deploy rolls, the agent hits an unhandled exception on a malformed tool response at 3am. If your loop resumes from durable state, a restart costs you seconds. If it does not, it costs you the run.
Egress and logs are the whole observability story. An agent talks to an LLM API and to whatever tools you gave it, so it needs outbound network. And because you cannot attach a debugger to something that only misbehaves once a day, structured logs on every iteration (which tool, which arguments, what came back) are how you find out what your agent actually did.
Why functions are the wrong default here
The instinct is to reach for serverless functions, because agents feel event-driven. It fights the model more than it helps.
Functions are built for request-and-forget work inside a bounded execution window. An agent loop holds context across many model calls, keeps connections open, and can legitimately run for minutes. You end up either fighting the timeout or shredding the loop into a state machine across a dozen invocations, which is a lot of engineering to make the wrong shape fit.
Functions are still useful here. They are a good home for the individual tools your agent calls, where request-and-forget is exactly right. The loop itself wants a long-running service.
The isolation question, honestly
Here is the part that matters more for agents than for ordinary services.
Your agent executes what a model told it to execute. Maybe it shells out. Maybe it runs generated code. Maybe it just fetches a web page, and that page contains text engineered to steer the next tool call. The blast radius of agent code is decided at runtime, not at review time, which is not true of the CRUD service running next to it.
Most container platforms run your workload as a process in a shared kernel, isolated by namespaces and cgroups. That is genuinely good isolation and it holds up for the overwhelming majority of workloads. It is also, by construction, one kernel vulnerability away from your neighbours. That is a well-understood trade-off and plenty of people accept it knowingly.
We think agent code is the workload where you should think twice before accepting it by default. So on Scalix Run, every deployment gets its own microVM: its own kernel, its own memory boundary, hardware-level isolation. The obvious objection is startup cost, and it used to be a real one. MicroVMs boot in roughly 76ms on our hardware, which is why this is the default tier rather than a premium one. You are not choosing between fast and isolated.
Packaging the loop
Nothing exotic. Your agent needs to be a process that starts, runs, and does not exit.
If it exposes an HTTP endpoint, so you can trigger it or check on it, listen on a port and read that port from the environment. If it is a pure worker driven by a queue or a timer, it just needs a main loop that blocks. Either way: no local state that matters, no secrets in the image, and logs to stdout.
You do not have to write a Dockerfile if you do not want one. Scalix Run deploys from source and detects the runtime from your package.json, requirements.txt, go.mod, Cargo.toml, or a Dockerfile if you have written one, and builds the image for you.
Deploying it
With a prebuilt image, the deploy is one command:
scalix-cloud run deploy --name agent \
--image api.scalix.world/<project-id>/agent:v1 \
--port 8080 \
--min-instances 1 --max-instances 5
Secrets go in as environment variables on the service. Through the API that is the env block:
curl -X POST https://api.scalix.world/v1/services \
-H "Authorization: Bearer $SCALIX_API_KEY" \
-d '{
"name": "agent",
"container": {
"image": "api.scalix.world/<project-id>/agent:v1",
"port": 8080,
"env": {
"MODEL_API_KEY": "...",
"DATABASE_URL": "postgres://..."
}
},
"scaling": { "min_instances": 1, "max_instances": 5 }
}'
The service comes up at a URL that does not change between deploys:
https://agent.run.scalix.world
Every deploy is a revision, so when a prompt change makes your agent worse in a way the tests did not catch, scalix-cloud run rollback <service-id> puts the old one back. Logs come back with scalix-cloud logs <deployment-id>.
Scale to zero, if your agent is bursty
Most agents are not busy. They wake up on a webhook, a schedule, or someone typing, do a few minutes of work, and go quiet. Paying for an instance that sits idle 22 hours a day is the default cost of agent hosting on most stacks.
Deploy with --min-instances 0 and the service scales down when nothing is calling it, then scales back up on the next request. Compute meters only while an instance is actually running. Two honest caveats: anything you keep, like stored data, bills whether the agent is awake or not, and an agent that has to react within seconds of an event should keep a floor of one instance rather than paying a cold start on every trigger.
The part that gets interesting
Your agent is now running on infrastructure. It can also operate that infrastructure.
We run a hosted MCP server at api.scalix.world/v1/mcp that exposes the platform as 50 tools: run queries and migrations, branch a database, deploy a service, check status and spend. One API key authorizes all of it, and that same key covers database, storage, functions, AI inference, and the registry. Point your deployed agent at it and the tools become things it can do.
Which means an agent can provision the database it needs for a new task, spin up a second service to handle a workload, check whether its deploys landed, and check what all of that cost. It is the same capability we wrote about when a coding agent deploys your app, except the agent doing the operating is the one you deployed. Give that scoped keys and approval gates on the destructive actions, the way you would with any other operator.
Where we are
Being straight about the stage: one EU region today, India next. When something breaks you get the two engineers who built it rather than a support tier. We publish uptime at status.scalix.world so you can check the claim rather than take it.
If you have an agent on your laptop that should be running somewhere else, Scalix Run is where to put it. Deploy it, point it at the MCP server, and let it run its own infrastructure. Come tell us what breaks on Discord.
FAQ
How do I deploy an AI agent to the cloud?
Package your agent loop as a container that stays running, deploy it as a long-running service, pass your model provider key in as an environment variable, and point its state at a managed database instead of local disk. On Scalix Run that is one deploy command against a source directory or a prebuilt image, and you get back a stable URL at https://<name>.run.scalix.world.
Can I host an AI agent on serverless functions?
You can host the pieces of one, but the loop itself fits badly. Functions are built for request-and-forget work with a bounded execution window, and an agent holds context across many model calls, keeps connections open, and may run for minutes or hours. A container service is the closer shape, with functions used for the discrete tools the agent calls.
Where do I store the API keys my agent uses?
As environment variables on the service, never in the image and never in the repository. Your model provider key, your database URL, and any third-party tool credentials get injected at deploy time, so rotating one is a redeploy rather than a rebuild. On Scalix, a single Scalix API key also covers database, storage, functions, AI inference, and the container registry, which cuts down how many secrets the agent has to carry at all.
Is it safe to run an AI agent in a shared container?
It depends on how much you trust the code paths a model can reach. An agent that shells out, runs generated code, or fetches and parses untrusted content is executing decisions made at runtime, which is a wider blast radius than ordinary application code. Shared-kernel containers put that workload one kernel bug away from its neighbours. Scalix Run puts each deployment in its own microVM with its own kernel instead.
How much does it cost to host an agent that is idle most of the time?
Set min-instances to 0 and the service scales down when no requests arrive, so compute meters only while an instance is actually running. That suits bursty agents well. Note that anything you keep, such as stored data and object storage, continues to bill whether the agent is awake or not, and an agent that must react to events every few seconds is better run with a floor of one instance.