DR2 Architecture Questions — Dispatcher on LXC, initiator without rendering, and GPU denoising ownership

Hi,

We run a small render farm with a custom Python-based job manager built on top of the AppSDK. Rather than using Backburner or another off-the-shelf solution, we control DR2 directly via the AppSDK Python API — which is why we’re in this corner of the forum rather than the general problems section.

We’re now redesigning the architecture and have a few questions before building it out.

Planned architecture:

		DR2 Dispatcher
		Dedicated LXC container (no GPU)
		Always-on, permanent
		AppSDK


		DR2 Initiator
		q5 — bare metal, RTX 3070
		Starts jobs via AppSDK, 0 buckets
		AppSDK


		Render hosts
		q1–q7 — bare metal Linux
		vray -server
		Standalone


		Windows render host
		w1 — Windows 11
		vray -server
		Standalone

All components use the same V-Ray build — revision 33551 — which is confirmed DR2-capable across AppSDK, Standalone, and Windows.

Question 1 — Initiator + render host on the same machine

Can the AppSDK initiator (configured to render 0 buckets itself) and a separate vray -server process run simultaneously on the same machine (q5)?

The idea: q5 runs the AppSDK renderer as pure job coordinator, while a second process — vray -server — connects to the dispatcher as a regular render host, contributing q5’s CPU to the farm like any other node.

Is this a supported configuration, or will there be port conflicts / protocol issues?


[/HR]
Question 2 — Dispatcher on LXC or Docker

Is running the DR2 Dispatcher inside a Linux LXC container (or Docker) a supported and recommended setup? Any known issues with containerized dispatchers?


[/HR]
Question 3 — Version matching with a permanent dispatcher

If the dispatcher runs permanently on a dedicated LXC, does it need to be updated every time the render hosts are updated to a new V-Ray version? Or is there any tolerance at patch level between dispatcher and render hosts?

In a previous thread (#1246429) a Chaos developer confirmed “version must be exact match” — does this apply to the dispatcher↔render host relationship as strictly as it does for other components?


[/HR]
Question 4 — Who owns bucket collection and GPU denoising?

In our setup, q5 (the initiator) has a GPU (RTX 3070). Is the initiator always responsible for collecting rendered buckets and running the final GPU denoising pass? Or can denoising be offloaded to one of the render hosts?


[/HR]
Thanks in advance — happy to share more details about the setup if helpful.

​Kind regards
algato

Update — tested the proposed architecture, works

We ran a production job with the described setup today:

  • Initiator/runner: AppSDK on q5
  • Render nodes: V-Ray Standalone vray -server -portNumber=20209 on q1–q7
  • All components: V-Ray 7.30.03, revision 33551

Result: fully functional. AppSDK initiator connected to all Standalone nodes without issues, distributed rendering worked correctly.

One additional observation regarding Question 4 (GPU denoising): during the render, nvidia-smi showed the GPU (RTX 3070) at 95% utilization — owned by the python3 process (the AppSDK runner, PID confirmed), not by the vray.bin Standalone process. This confirms that the initiator is responsible for GPU denoising, not the render nodes.

Update — Cryptomatte issues with DR2: two different failure modes

Following up on our architecture tests. We discovered two distinct Cryptomatte failure modes depending on dispatcher location.

Phase 1 — Dispatcher running locally on q5 (same machine as initiator)

DR2 rendered successfully across all nodes. However, Cryptomatte render elements in the output were faulty — incorrect or incomplete data. The render itself completed without hanging.

Phase 2 — Dispatcher moved to dedicated LXC container (external)

With the dispatcher on a separate host, any job containing RenderChannelCryptomatte now hangs indefinitely after scene load:
Waiting for cryptomatte manifest…

No timeout, no error — CPU on all render nodes drops to 0%. The process must be killed manually.

Environment: AppSDK VRayRenderer, enableDRClient(dispatcher=“192.168.1.7:20210”), V-Ray revision 33551, vrscene exported from 3ds Max 2025 with Cryptomatte render element active.

Workaround attempted: Regex-stripping RenderChannelCryptomatte blocks from the vrscene before renderer.load() — prevents the hang but sacrifices Cryptomatte output entirely, which is not acceptable for production.

Since all our production jobs include Cryptomatte, we’ve temporarily fallen back to Classic DR (vray -distributed=1) which completes correctly including Cryptomatte output.

Questions:

  1. Is the faulty Cryptomatte output with a local dispatcher a known issue?
  2. Is there a supported API method to disable RenderChannelCryptomatte at the AppSDK level before rendering, without modifying the vrscene file?
  3. Is the manifest hang with an external dispatcher a known bug — and is a fix planned?

We would very much like to return to DR2 once this is resolved.

Update — Cryptomatte confirmed broken in DR2, working in Classic DR

After extensive testing we can now report a clean A/B comparison — same scene, same nodes, same V-Ray build (revision 33551), nothing reinstalled:

Classic DR (vray -distributed=1): All Cryptomatte layers (OBJ, MAT, LAY) output correctly and are fully readable in Nuke.

DR2 (AppSDK VRayRenderer + enableDRClient): Two distinct failure modes depending on dispatcher location:

  • Dispatcher on the same machine as the initiator: Render completes, but Cryptomatte output is damaged — only partial layer data.
  • Dispatcher on a separate host (LXC container): Render hangs indefinitely — Waiting for cryptomatte manifest… — all nodes drop to 0% CPU, no timeout, process must be killed manually.

Simply switching from DR2 to Classic DR resolved the Cryptomatte output completely. This confirms the damage is caused by DR2 itself, not the scene or the nodes.

Note: We are also tracking a separate Cryptomatte regression in EXR metadata writing (thread #1247035) — that is a distinct issue unrelated to the DR mode.


[/HR]
Additional question — dispatcher port

We have been running our DR2 dispatcher on port 20210, with render servers on 20209. We chose 20210 ourselves to avoid conflict when dispatcher and render server run on the same machine — but we could not find this confirmed in official Chaos documentation. Is 20210 the intended default for the DR2 dispatcher?

Here’s what the devs answered:

We recommend to run the dispatcher in rendering mode. As if they were two separate processes, they would load the scene twice independently. And yes, they would have to use different ports for the two processes.

We don’t see a problem as far as we know, containers are running the code bare metal, so it should be fine.

Yes, it’s best to match them.

We’ll have to check, but we think the denoiser runs on the client when the final image is composed.

We need to investigate this.

Yes, very easy, e.g., to delete the RenderChannelCryptomatte plugin, you can simply add this to your script:

plg = renderer.classes.RenderChannelCryptomatte.getInsta nce()
if plg: plg.deleteThis()

We need to investigate this, also.


The defaults are written in this docs page.​

Hello Aleksandar,

Thank you for the detailed answers — that clears up the architecture side, and the RenderChannelCryptomatte.getInstance() / deleteThis() snippet is very good to have in the toolbox.

For the time being we’re staying on Classic DR: cryptomatte is part of our daily pipeline and Classic handles it cleanly, so we have no production pressure. We’ll revisit DR2 with an upcoming V-Ray release to see how things evolve.

Thanks again for the thorough reply.

Best,
algato