Wrangle
Build log

What we measured building on Deadline Cloud.

Wrangle is an operations layer for studios running AWS Deadline Cloud without a pipeline engineer to babysit it. It is not finished, and this is not a changelog.

It is the findings log. Building this meant standing up a real farm, breaking renders on it deliberately, and reading what came back — and most of what we learned is not written down anywhere public. So it is written down here, with the numbers attached and the date they were taken. 3 of the entries below are walls in someone else’s product. 6 are defects of our own.

The measurement the whole product is built on
51 secRendering ten frames on the farm, once it existed.
1 full sessionGetting to the point where rendering was possible at all.
Four AWS services, two hard dead-ends, one forced sign-out, one support-case escalation, one undocumented cap, and roughly nine credential and consent ceremonies — driven by an operator who already knew where everything was. The compute was never the hard part. That asymmetry is the entire reason this company exists, and we measured it before we wrote a line of the product.

Findings

14 entries · newest first

Each one was taken off a live farm and is traceable to a file in the repository. Where an entry is our own mistake it says so, because those were the more useful half.

deadline cloud · adaptorsmeasured

The per-application render adaptors are already on the farm's own channel

CondaPackages: blender-openjd
downloaded 444.9 MB/444.9 MB (2/2 packages complete), 426.2 MB cached
blender          5.1.2   deadline-cloud
blender-openjd   0.6.1   deadline-cloud

AWS publishes a render adaptor for ten applications — Blender, Maya, Houdini, Nuke, Cinema 4D, 3ds Max, Unreal, After Effects, KeyShot, VRED — under Apache 2.0. We had assumed adopting one meant installing it onto workers ourselves, and costed a slower cold start for it.

It resolves straight from the deadline-cloud conda channel the queue already defaults to, and pulls the application itself as a dependency — so it replaces blender in the package list rather than adding to it. The expensive half of that plan did not exist.

This does not generalise across the channel, which is why it was measured rather than reasoned. The bundling libraries deadline-cloud-job-attachments are not there — we hit that wall in June. Render-side adaptors are; asset-side libraries are not.

What it changedThe adaptor keeps the application open between frames instead of launching it per task. On a 250-frame shot that is one launch instead of two hundred and fifty, on the studio’s bill — which makes it the cheapest performance available to anyone building here, and it was sitting one package name away.
wrangle · submissionour defect

We sent a scene to the farm without the textures it asks for

scene staged alone, read by Blender's own parser on the farm:
  //tex/grid_diffuse.png   referenced, not sent
  //tex/panel_rough.png    referenced, not sent

A submission sent the file the artist picked. A scene is not one file — it points at textures, caches, references — and nothing read it, so nothing knew. The render either fails on the farm or comes back quietly wrong, and the person who submitted it finds out in the morning.

Reading the scene is the fix, but the scene has to be held to be read, and customer assets never enter our account. So the reading happens on the studio’s own machines, using the application’s own parser — never a format reader of ours, which would be a per-application maintenance tax whose failure mode is a silently incomplete render.

The same read answers questions we had been asking the artist to type. That scene declares frames 1–250, EEVEE, saved with Blender 5.1. Our form had a frame range defaulting to 1–1, which meant the obvious path rendered a single frame of a 250‑frame scene and said nothing about it.

What it changedAnswers are remembered against the scene’s content hash, so an unchanged file is never uploaded or read twice, and an edited one is never answered from cache. Nothing here is inferred from a filename or a folder layout — the file is opened, or we say we do not know.
deadline cloud · workersmeasured

The farm forgets which machines ran your renders

our record of the same window : 37 sessions, 18 workers, 1 fleet
aws deadline search-workers   : 0

Both numbers were taken within a minute of each other. Every one of those eighteen machines had already been forgotten by the platform: the fleet scaled to zero and took the worker records with it.

The session records survive a while longer, which is the only reason the history was recoverable on the day we went looking. After that, “which machine ran this shot, and for how long” is not answerable at any price. There is no archive to page back through — either something wrote it down while the fleet was warm or the answer is gone.

What it changedMost things in a render pipeline can be recomputed. This one cannot, so it is the first thing we started recording — before anything that reads it exists. A studio asking in November what its August GPU hours went to is asking a question only something that was watching in August can answer.
our own build · vercelour defect

The build that shipped this page failed, because a local build is not the same build

local   pnpm build  ->  green   (.env.local auto-loaded by Next)
vercel  pnpm build  ->  Error: Invalid server environment
                          DATABASE_URL: received undefined

Releasing this page failed on the first attempt. The auth module is built lazily on purpose, so that importing it never reads the environment — but one line called it at module scope, and Next evaluates route modules at build time. So the build demanded a database password it had no use for.

Every gate had passed locally. They passed because Next auto-loads .env.local, so the local build was quietly holding the exact secrets production does not have. It was never evidence about production — it was the same test run with a privilege production lacks.

What it changedThe same shape as the CloudFormation entry below, four days apart: verifying through a path that carries a privilege the real one does not have proves nothing. The gate is now to build with the environment file moved away, which is the only version of that check that means anything.
deadline cloud · cost apimeasured

The cost API rounds to whole cents, so most shots cost $0.00

instance         n   cost.min   cost.max   cost.avg   cost.sum
c5.4xlarge      20    0.00043    0.02678    0.00000       0.04
c5.4xlarge       4    0.00069    0.00159    0.00000       0.00
c5ad.4xlarge     7    0.00071    0.00242    0.00000       0.01
c5d.4xlarge      2    0.00097    0.00199    0.00000       0.00
c6i.4xlarge      2    0.00098    0.00308    0.00000       0.00

Deadline Cloud will aggregate session statistics for you, and the response carries a costInUsd field. Run it over real work — 37 sessions, 1,231 seconds of compute across four instance types — and the precision is not uniform. min and max carry five decimals; sum and avg carry two.

Four of seven rows report sum: 0.00 while carrying real per-session cost. avg is 0.00000 in six of seven. A naive rollup of the field that looks most like a total returns six cents for the entire window and silently discards every sub-cent row.

What it changedA per-shot cost built on sum reads $0.00 for most real shots. That is not a rounding nicety, it is a number that lies quietly. We price runtime by instance type ourselves and keep min/max as the cross-check.
aws stsour defect

Five different mistakes return a byte-identical error

wrong external id   ->  AccessDenied
missing role        ->  AccessDenied
wrong account       ->  AccessDenied
malformed role arn  ->  AccessDenied
our own token dead  ->  AccessDenied

Connecting a studio’s farm means assuming a read-only role in their AWS account. When that fails, STS returns the same AccessDenied text for at least five distinct causes — four of them theirs, one of them ours.

So any error message that names a single cause is guessing. Ours guessed. It told a studio their IAM role was misconfigured when the real cause was our own expired session token — we sent them to go fix something that was working.

What it changedThere is now one classifier that every handler must call, and it states the ambiguity instead of picking a favourite. Two rules came out of it and are enforced rather than remembered: never leak an internal identifier into customer-facing text, and never tell someone to fix their side when the failure is ours.
cloudformationour defect

Our own onboarding link was broken, and only the customer's path showed it

Connecting a farm hands the studio a CloudFormation quick-create URL with the parameters pre-filled, including a per-connection external ID that guards against the confused-deputy problem. That parameter was marked NoEcho: true, which is correct — it is a secret.

Quick-create links silently drop NoEcho parameters. The external ID never arrived, so the stack could not be completed and the connection could never verify. We had not noticed because we deployed our own stack from the CLI, where the parameter passes normally.

What it changedNever treat a CLI-deployed stack as proof the customer path works. They are different code paths with different rules, and only one of them is the product.
deadline cloud · read apiour defect

A job's own status field says READY while one of its tasks is running

taskRunStatus:       "READY"
taskRunStatusCounts: { "RUNNING": 1, "SUCCEEDED": 5, "READY": 0 }

Both of those lines came out of the same get-job payload. The job-level taskRunStatus is not an aggregate of the job’s tasks — it appears to describe the next task to schedule.

Trust it and a dashboard says queued over work that is visibly running. Ours did, and we only found it because we submitted two real renders to prove a colour was reachable.

What it changedDisplayed status is derived from the counts that already drive the progress bars. The platform’s own status word is kept as the record and as the fallback for what counts cannot answer — but it is never what the screen says.
deadline cloud · retriesmeasured

The farm re-ran a corrupt scene twelve times

corrupt scene   -> 12 sessions  (File format is not supported)
missing binary  ->  6 sessions  (exited with code: 127)
canceled midrun ->  1 session   (no error text at all)

We broke renders on purpose to see what the farm does with a failure it cannot win. A scene Blender cannot open burned twelve sessions. A missing renderer binary burned six.

Both failures are deterministic. Attempt two was never going to work, and neither was attempt twelve. Each one leases a worker and bills for it.

What it changedThis is the measured case for triage that runs before a retry rather than after it. Two failure classes must never be requeued at all: a missing plugin or binary will still be missing on the next attempt, and retrying into an exhausted licence pool burns worker-minutes waiting for a seat that is not free.
deadline cloud · logsmeasured

A canceled task produces a completely clean log

Cancel a render mid-run and the session log shows normal setup, normal cleanup, and no error text of any kind. Nothing in the log distinguishes it from a healthy run.

Anything that classifies failures by reading logs will call that task fine. The truth is only in the run-status transitions on the event stream.

What it changedLogs are evidence, never verdicts. Status comes from events; the log is what you read once you already know something went wrong.
aws service quotasplatform wall

There is an undocumented cap of two pending quota requests per account

default on-demand vCPU   50    (raised: automatic)
default spot vCPU        50    (raised: support case)
default GPU               0    (blocked)

A new Deadline Cloud account starts at 50 on-demand vCPU, 50 spot, and zero GPU. Fifty vCPU is three of the instances the setup wizard itself recommends, so every studio doing real work has to raise these before the farm is usable.

Raising GPU from 0 was refused — not on merit, but because two other quota requests were already pending. The cap is not in the docs and the error only appears at submit time, after the form is filled.

What it changedQuota raises are the long pole in any real setup: some are instant, some open a support case that takes days, and the order you file them in changes whether they are accepted. That sequencing is exactly the kind of thing a studio should never have to discover.
deadline cloud · setup wizardplatform wall

The guided setup dead-ends by telling the buyer to contact their IT admin

"No groups in your management instance.
 Contact your IT admin."

That is step 2 of the guided farm setup — a hard stop, no link, no inline fix. At a 30-person studio the person reading it is the IT admin.

The groups it wants live in a different service (IAM Identity Center) inside a different account (the organisation’s management account). Nothing on the screen says so. You need to already know the shape of AWS Organizations to understand what you are being asked for.

What it changedThe wizard is genuinely fine once its prerequisites exist. Every wall we hit was before it — which is what makes setup a product rather than a support article.
aws consoleplatform wall

Fixing that dead-end signed us out and reset the wizard to step one

Resolving the previous finding means opening a second AWS account’s console. Multi-session is off by default, so opening the management account silently ended the session in the first one.

No warning, no prompt. Wizard state gone, sign in again, start from screen one — while holding in your head the thing you left to go fix.

What it changedTwo accounts is the correct architecture and it is what we run. It is also a trap the default browser behaviour sets for anyone crossing between them mid-task.
our own buildour defect

The dashboard felt loose because the design it copies renders in quirks mode

prototype  job row: 16.0px / 25.5px   <- no doctype, quirks mode
ours       job row: 11.5px / 22.67px  <- inherited the body font

The verdict on the first cut of the dashboard was that it “doesn’t have the tightness” of the design it is meant to copy. Reading both stylesheets side by side explains nothing: they agree.

Dumping computed styles from both pages at one viewport found it in a minute. The ratified design file has no <!doctype>, so it renders in quirks mode — where table cells do not inherit the body font and fall back to 16px. That one-step size difference was the entire gap.

What it changedFidelity is judged on rendering, so it gets verified by measuring, never by reading CSS. The measured values are now written down explicitly — not reproduced by dropping our own doctype to inherit a browser quirk.

Where the build actually is

45 of 95 tasks closed
Straight off the build plan in the repository. Phase 1 ships the monitor; nothing after it is started.
PhaseClosedOpenState
Phase 0 · Proving ground74GPU quotas still pending with support
Phase 1 · Watch2810in progress — monitor is live on real farm data
Phase 2 · Land1012setup + web submission
Phase 3 · Account012cost per shot, tracker sync
Phase 4 · Wrangle010overnight triage
Phase 5 · Scale02demand-pulled, nothing scheduled

Looking for two design partners.

The findings above came from a farm we broke on purpose. The next set has to come from farms doing real work — which means two studios willing to point a read-only role at their Deadline Cloud account and tell us where the dashboard is wrong.

Read-only, scoped to one bucket prefix, revocable by deleting one CloudFormation stack. You keep the compute, the account, the data and the bill. If you are running Deadline Cloud without a pipeline engineer, that is the conversation we want.

Wrangle · built on AWS Deadline Cloud, not instead of itLast finding 2026-08-27 · hello@wrangle.cloud
Ayudh