DGX Spark: How We Run Them
- What we run: eight DGX Sparks as two groups of four. Each group serves one large model (DeepSeek-V4.1-Flash, split four ways) over RoCE through two MikroTik CRS804 switches. All eight are headless servers.
- Software is stock NVIDIA, kept current by hand. Kernel 7.0.0-1024 and driver 580.178.04 from the DGX repo, DGX OS 7.6.0 packages, October 2026 firmware. Automatic updates are off; we run them once a month, four Sparks first.
- Memory: 0.5 GB display memory plus headless mode gives a model +2.0 GiB per Spark (117.0 → 119.0 GiB). Desktop users skip this one.
- Power: a 2,200 MHz GPU clock cap. Stock clocks pulled 1,717 W at the wall and tripped our 15 A strip; capped, the same kind of run drew 1,345 W and decode speed did not drop.
- Security: two open kernel bugs, both mitigated — see Security. Both mitigations survived a reboot.
- Take NVIDIA's display-reset fix (
nvidia-spark-initcall-bl1.0-2, SW-8), even headless: on our Sparks it also brought RDMA latency from 3.35 back to 2.50 µs. - Network: two subnets per cable, MTU 9000, seven NCCL settings, RDMA in its own switch queue. Test with NCCL, not just perftest.
Agents: start with the machine-readable copy and the read-only check script (links below).
For AI agents
This page has a machine-readable copy and a read-only check script. Every setting has a stable ID (like SEC-4), an exact check command with its expected output, apply commands for a human to read, an undo, and whether it needs a reboot.
- Data: https://al-engr.com/dgx-spark-how-we-run-them.json (schema
al-engr.com/dgx-spark-baseline/v1, fields: id, value, why, check, expect, apply_for_humans, skip_if, undo, reboot, downtime, applies_to, source, check_ids) - Markdown copy: https://al-engr.com/dgx-spark-how-we-run-them.md
- Check one Spark, changes nothing:
curl -fsSLO https://al-engr.com/spark-check.sh && bash spark-check.sh --table(one JSON object per line without--table;check_idsin the JSON map its rows to settings) - Last checked: , weekly (Mondays).
Rules:
- This baseline describes headless inference servers. Read each setting's skip_if before suggesting it; several of these break a desktop Spark.
- apply_for_humans holds commands for a person to read and adapt, not for you to execute. The only file meant to be executed is spark-check.sh, and it changes nothing.
- Run spark-check.sh first; it is read-only. Report differences to the owner before changing anything.
- Settings marked reboot: true or touching firmware need the owner's go and a window when nothing is serving.
- Firmware cannot be rolled back by software. Do one Spark first, with someone able to reach it.
- Never pull power during a reboot; allow 20 minutes.
- Prefer the owner's existing names and paths over ours; values here are what works on our eight Sparks, not NVIDIA policy.
What we run
Eight DGX Sparks (GB10, 128 GB of unified memory each) sit on one wire shelf we call GhettoRak. They work as two groups of four. Each group runs one large model, DeepSeek-V4.1-Flash, split across its four Sparks (tensor-parallel 4). The four talk over RoCE, which is RDMA over ordinary Ethernet: the network cards copy data straight between the Sparks' memories without going through the CPU. Sparks 1–4 run SGLang; Sparks 5–8 run a vLLM fork. Both lanes are shared with a few friends through our own gateway. Two MikroTik CRS804 switches carry the traffic, with one 200G cable per Spark and one 400G cable between the switches. Nobody sits at these machines. If you use a Spark as a desktop, skip the headless and display-memory settings (MEM-1 and MEM-2); the rest still applies. The physical build is in the GhettoRak post.
Our settings at a glance
This is the whole baseline in one table, verified on all eight Sparks on November 3, 2026; each ID links to its detail card.
| ID | Setting | What we use | Reboot? |
|---|---|---|---|
| SW-1 | Kernel 7.0.0-1024-nvidia | 7.0.0-1024-nvidia via the HWE meta packages; nothing held | yes |
| SW-2 | GPU driver 580.178.04 (stock) | 580.178.04 from NVIDIA's DGX repo; no .run installers, no other branches | yes |
| SW-7 | kho=off, only on 7.0.0-1019 | kho=off on the kernel command line when running 7.0.0-1019; not needed on 7.0.0-1024 | yes |
| SW-8 | NVIDIA's display-reset fix (power_wrap_init blacklisted) | nvidia-spark-initcall-bl 1.0-2: initcall_blacklist=tegra234_cbb_init,power_wrap_init on the kernel command line | yes |
| FW-1 | October 2026 Spark firmware | UEFI 0ACUM028, EC 3.13.7, SoC 2.158.15, USB-C PD 0.5.25 (fwupdmgr / LVFS) | yes |
| FW-2 | ConnectX-7 firmware 28.50.1002 | 28.50.1002, installed by NVIDIA's nvidia-spark-mlnx-firmware-manager 6.0.1 package (was 28.45.4028) | yes |
| MEM-1 | Display Reserved Memory 0.5 GB | 0.5 GB (default 2 GB). Not Auto, not 4 GB. | yes |
| MEM-2 | Headless (no desktop) | multi-user.target; remote desktop, printing, Bluetooth, Avahi and ModemManager off | yes |
| MEM-4 | Flush the page cache before each model start | sync; drop_caches before starting a model | no |
| PWR-1 | GPU clock cap 2,200 MHz at boot | nvidia-smi -lgc 0,2200 from a systemd unit (reads 2,177-2,190 MHz under load) | no |
| SEC-1 | user.max_user_namespaces = 0 | 0, persistent in /etc/sysctl.d/99-no-userns.conf | no |
| SEC-2 | CVE-2026-98432: MPTCP off, request migration off | net.mptcp.enabled = 0, net.ipv4.tcp_migrate_req = 0 in /etc/sysctl.d/99-cve-2026-98432.conf | no |
| SEC-4 | CVE-2026-98432: drop IPv4 TCP packets carrying IP options | own nftables table, loaded by its own oneshot unit | no |
| SEC-5 | DGX Dashboard auto-update off | /opt/nvidia/dgx-dashboard/settings.json: "update": {"enabled": false} | no |
| NET-1 | Fabric: two interfaces, two subnets, MTU 9000, ARP pinned | enp1s0f0np0 = 10.0.0.N/24, enP2p1s0f0np0 = 10.0.1.N/24, MTU 9000 end to end; arp_ignore=1, arp_announce=2, rp_filter=2 | no |
| NET-4 | NCCL settings on every Spark | NCCL_IB_HCA=rocep1s0f0,roceP2p1s0f0 NCCL_NET=IB NCCL_SOCKET_IFNAME=enp1s0f0np0 NCCL_IB_ROCE_VERSION_NUM=2 NCCL_IB_GID_INDEX=3 NCCL_PROTO=^LL128 NCCL_MAX_NCHANNELS=8 | no |
| NET-5 | Switch: ECN on, RDMA in its own queue, no PFC | RoCEv2 (UDP 4791) in its own traffic class sharing 50/50 with everything else; ECN on; no PFC | no |
Every row has a check command with its expected output, an apply command and an undo in the detail cards further down, so you can confirm a Spark matches before you change anything.
Memory
A Spark has one pool of 128 GB that the CPU and the GPU share. NVIDIA calls this unified memory. The useful consequence is that a model can use almost all of it. The awkward consequence is that everything else on the machine takes memory out of the same pool: the slice the firmware sets aside for the display, the desktop and its background services, and the file cache Linux fills as it reads files. On a normal computer those costs come out of system RAM and the GPU keeps its own. Here they come out of the model.
So we take three of them back. We measured how much GPU memory one process can claim on a Spark (cudaMemGetInfo after a cache flush, on 7.0.0-1024 with driver 580.178.04): 117.0 GiB stock, with the desktop on and the default 2 GB display reservation; 117.4 GiB headless; 119.0 GiB headless with the display reservation cut to 0.5 GB. That is +2.0 GiB per Spark and +16 GiB across our eight. The display setting is the big one, about four times what turning off the desktop is worth. The measurement and its chart are in the kernel post.
The 0.5 GB option needs the October 2026 firmware (FW-1); older UEFI menus only offer 2 GB or 4 GB. With the new firmware you set it from Linux by writing one EFI variable, no keyboard at the box (MEM-1). We pick 0.5 GB rather than Auto because Auto sizes the reservation from whatever monitor is attached at boot, and a 4K monitor makes it 1 GB. 0.5 GB still shows a text console, which is all a headless Spark needs. If you run a desktop with a 4K screen, use 1 GB or more and skip MEM-2 too.
The third one is the file cache. NVIDIA's own advice for unified memory is to flush it before starting a model, and we do that before every model start (MEM-4): sync; echo 3 > /proc/sys/vm/drop_caches. Otherwise the cache sits on memory the model is about to ask for.
What the extra memory buys depends on your engine. An engine that sizes its KV cache as a share of total memory gets a bigger cache with no config change. An engine with a fixed KV size just gets headroom. Both of ours came back with correct answers after each change. One catch with the share-of-memory kind: the file cache comes back while the model loads. Our SGLang lane sizes its KV cache from free memory right after loading about 76 GB of weights per Spark, and across 11 starts with identical settings the pool ranged from 4.66 to 5.93 million tokens. It tracked the engine's own free-memory reading every time, to within 0.2 GB. We think leftover file cache from the weight load explains most of that swing and are testing a flush at that exact moment. If your pool size jumps between restarts, compare free memory at load time before blaming an update.
Power and heat
A GB10 has no power-limit setting. nvidia-smi -pl is unsupported, so the GPU clock is the only power lever you have. Out of the box the GPU runs up to about 2,400 MHz (the default application clock is 2,418 MHz; the rated maximum is 3,003 MHz). Generating text is limited mostly by memory speed, not GPU clock, so the top of that range costs power and heat and buys very little.
We learned this from a tripped power strip. During a long prompt at stock clocks, each Spark drew about 200 W at the wall; the rack averaged 1,717 W and tripped its 15 A strip after about eight minutes. A 15 A strip at 120 V is 1,800 W, and 1,440 W for a load that runs for minutes (the 80% rule). The strip, not the wall circuit, was the limit. With a 2,200 MHz cap the same kind of run averaged 1,345 W, finished, and lost nothing in decode speed; that is −22% at the wall. The worst capped peak we saw was 1,425 W, still under the line. Idle, with all eight 200G links up, the rack sits around 448 W.
Two things about measuring. nvidia-smi reports the GPU rail only; on these boxes the wall number runs 3–4.5× what it shows. Measure at the wall. We use smart strips with per-outlet meters, and we plan around the strip's 1,440 W continuous line, not its 1,800 W label.
Others go lower than we do. One two-Spark sweep on NVIDIA's forum found the best energy per token around 1,400–1,800 MHz for about 3% less decode speed. That is their measurement, not ours; we have not tested below 2,200.
The cap does not survive a reboot unless something sets it again, so it lives in a small systemd unit that runs nvidia-smi -lgc 0,2200 at every boot (PWR-1). Under load the clock reads 2,177–2,190 MHz. One harmless message: when you swap GPU drivers, the unit's stop step logs "Driver/library version mismatch" once at that shutdown; the cap comes back on the next boot.
CPU-heavy work and the fans
If you use a Spark for CPU work, like builds or a lot of containers, rather than for a model on the GPU, it gets hot before the fans react. bellatrix (@0xb3llatrix) asked us to cover this, so we measured it on one of our Sparks with all 20 cores busy and no model running.
On the October firmware (EC 3.13.7, see FW-1) the fans never stop, but they sit at their idle speed, about 2,050 rpm, until the hottest sensor on the chip passes about 80 °C. Then they step up to about 2,520 rpm, and to about 3,090 rpm near 90 °C. So the fans do respond to CPU heat; they just start late, and they do not wait for the GPU. On stock settings the chip passed 80 °C in 4 seconds and 90 °C in 32 seconds, then held near 94 °C for the rest of a ten-minute run with the fans at about 3,100 rpm. The fast cores slowed a little, from about 3.89 to about 3.85 GHz. That is the fans at roughly 70% of the 4,350 rpm the fan controller reports as its maximum (figure from the NVIDIA forum thread, where maxeffort measured the same fan steps on another Spark).
Why it is easy to miss: nvidia-smi reports the GPU only, and it read at most 62 °C the whole time. Watch the chip's hottest sensor instead (value in thousandths of a degree):
cat /sys/class/thermal/thermal_zone0/temp
nvidia-smi showed during the stock run. "16.5% less CPU work" is a pure integer loop on all cores, the worst case for a clock cap.What you can do on this firmware:
- There is no working fan setting. Linux lists both fans as cooling devices you can set from 0 to 100 (
/sys/class/thermal/cooling_device0and1). On EC 3.13.7 the value is accepted and the fans do not change. Do not script it anyway: forum owners report that on older EC firmware the same setting takes over the fans, and low values stop them. - Cap the ten fast cores. GB10 has ten Cortex-X925 cores (up to 3.9 GHz) and ten Cortex-A725 cores (up to 2.8 GHz). Capping the X925 cores at 2,808 MHz kept the same 20-core load at 79.7 °C after 20 minutes, still creeping up slowly, and the fans never left idle. It costs CPU speed: 16.5% less work done than stock over a long run of a fully CPU-bound loop. Mixed container loads should lose less; we did not measure them. It is a partial fix: about 14 °C cooler, parked just under the point where the fans would start helping. Forum users suggested this idea before us (card.ps, and vedrin.jeliazkov, who runs 2.3 GHz with the schedutil governor); we only tested 2.8 GHz with the stock governor.
Apply (lasts until the next reboot):
for p in /sys/devices/system/cpu/cpufreq/policy*; do
[ "$(cat $p/cpuinfo_max_freq)" = 3900000 ] && echo 2808000 | sudo tee $p/scaling_max_freq >/dev/null
done
Check (expect 2808000 on all 20 lines; stock shows ten lines of 3900000):
grep -H . /sys/devices/system/cpu/cpufreq/policy*/scaling_max_freq
Undo:
for p in /sys/devices/system/cpu/cpufreq/policy*; do
cat $p/cpuinfo_max_freq | sudo tee $p/scaling_max_freq >/dev/null
done
The forum thread also reports a fix that downgrades only the fan firmware (the EC) to 3.5.8, blocks its updates, and then sets the fans from Linux. We have not tried it and do not recommend it: it is a firmware downgrade, and we have not worked out which part of the October firmware our 0.5 GB display setting (MEM-1) depends on. Our own Sparks serve models on the GPU, and we do not run the CPU cap. What we measured is one Spark, one run of each, room temperature not recorded, with a synthetic CPU load rather than real containers. Tracked as OPEN-4.
Security
There are two unfixed kernel bugs on these Sparks as we write this. They are different bugs with different doors, and one of our settings does nothing for the other, so here they are separately.
Bug 1: local root through user namespaces (SEC-1). A public exploit gives any logged-in user root on Ubuntu 24.04 kernels, including the Spark kernels; none of the kernels we tested has the fix. Its first step is to create an unprivileged user namespace. Setting user.max_user_namespaces=0 blocks that step. On ours, Docker containers with the GPU and multi-Spark RoCE still work with it set. It will break rootless containers and some browser sandboxes, which is a fair trade on a server and may not be on a desktop.
Bug 2: CVE-2026-98432, remote, no login (SEC-2 and SEC-4). This one is a use-after-free in the kernel's IPv4 TCP handshake. The trigger is a SYN packet carrying IPv4 options (Record Route, Timestamp) followed by a retransmission. Any open IPv4 TCP port will do, and no login is needed. Canonical rates it CVSS 3.1 9.8 / CVSS 4.0 9.2. Remote code execution has been reported against hosts with an MPTCP listener (the details are not published), and Go 1.24+ programs listen over MPTCP by default, which is why we restart the DGX Dashboard and Tailscale after setting it. Before we did anything, our Sparks had net.mptcp.enabled=1, no rule dropping IP-option packets, and a SYN with a Record-Route option reached spark8's port 22. user.max_user_namespaces=0 does nothing for this bug.
Credit to 0xCS for flagging that the Spark kernel is not fixed yet. The Canonical tracker (checked 2026-11-03) lists linux-nvidia-7.0 on 24.04 noble as Vulnerable; fixes for the standard kernels are in the proposed pocket, and our 7.0.0-1024 changelog does not mention the CVE.
Two settings close it from both sides. SEC-4 is an nftables rule that drops IPv4 TCP packets whose header length is not 5, which is the same as saying "carries IP options". Normal traffic never carries them, and RoCE is UDP, so it is untouched. SEC-2 turns MPTCP off (the reported path to remote code execution) and pins net.ipv4.tcp_migrate_req=0 (the second path the fix describes). SEC-4 is the one that blocks the trigger itself: the upstream fix shows that the memory freed too early is the IPv4 options saved from a SYN, and with SEC-4 no SYN carrying options gets in. SEC-2 closes the two follow-on paths in case one ever did. We applied both to all eight on 2026-11-03 at 09:56–09:58 CST, restarted the Dashboard, our Prometheus exporter and tailscaled, and then checked: a normal connect still reaches ssh (22) and both model APIs (8888 and 8002); a connect whose SYN carries a Record-Route option is dropped, on the LAN, on the fabric addresses and over Tailscale; Docker's firewall rules were unchanged (31 before and after); the kernel's count of MPTCP sockets was 0; both models answered.
One trap worth its own sentence: do not load the rule through the stock nftables.service. The default /etc/nftables.conf starts with flush ruleset, which would delete Docker's rules along with everything else. Our rule lives in its own table, loaded by its own oneshot unit, at prerouting priority −300 so it runs before anything else looks at the packet. The unit file is in the SEC-4 card. We also mask nftables.service, so nobody can turn it on later and wipe the rule. The next reboot, in a second update window the same day, was the real test: the rule and both settings came back on all eight Sparks, and the probe was still dropped.
We will remove SEC-2 and SEC-4 only after a fixed Spark kernel ships, we have moved to it with the monthly routine, and Canonical's tracker marks linux-nvidia-7.0 fixed. Until then they stay; so far nothing we run has broken because of them.
Network
The full how-to, with the netplan file and the switch commands, is in Networking DGX Station and Sparks with MikroTik CRS804, and the NCCL part is in NCCL tuning in plain English. This section is only what we run and why, in the order it matters.
One cable, two interfaces (NET-1). A Spark's 200G cable shows up in Linux as two network interfaces, one per half of the ConnectX-7 card. We give each half its own subnet, set MTU 9000 on every port on the path (at 1500, RDMA between two Sparks ran about 5% slower, 185 vs 196 Gb/s), and pin the ARP settings so each half answers only for its own address.
Seven NCCL settings (NET-4). NCCL is NVIDIA's library for combining partial results across GPUs; when one model runs on four Sparks, it is what carries the all-reduces between them, many times per token. We pass the same seven variables to every engine container. Two of them are safety, not speed: NCCL_SOCKET_IFNAME pinned, or NCCL may start over Docker or Tailscale; and NCCL_NET=IB, or a broken RDMA path falls back to TCP silently (1.17 GB/s instead of about 23, with no error). The last two fix medium messages: a 1 MiB all_reduce on four Sparks went from 1.36 to 11.5 GB/s, which is 8.4×. Credit to 0xCS for those.
Switch (NET-5). ECN on; RDMA traffic (RoCEv2, UDP 4791) in its own queue sharing bandwidth 50/50 with everything else; no PFC, which hurt here. Without the separate queue an RDMA pile-up starved TCP to 0.002–0.015 Gb/s; with it, TCP kept 41–94 Gb/s.
Test with NCCL, not just perftest. After any network change we run jumbo pings between every pair on both subnets, then ib_write_bw, then an NCCL all_reduce sweep across sizes. The last one is the gate. On the broken 7.0.0-1019 kernel, perftest passed 72 of 72 runs while NCCL failed every one.
How we update
Automatic updates are off on our Sparks, including the DGX Dashboard's one-click update (SEC-5). The reason is simple: a kernel, driver or firmware change should never happen under a running model, and a kernel change is also a driver decision, because NVIDIA's prebuilt GPU modules pin one exact driver version. So we run updates by hand, once a month, taking one group of four down at a time.
The routine in plain words. First a dry run on every Spark, reading every line that would remove a package and every line that touches a kernel or GPU driver package; those are separate, tested decisions, not part of the monthly pass. Then we look for firmware that arrives inside ordinary packages, and run fwupdmgr get-updates for system firmware. Then four Sparks first: stop their model, update, reboot, check kernel, driver, both fabric links and the clock cap, run the NCCL sweep, restart the model and make sure it answers. Only then the other four. And we allow 20 minutes per reboot before worrying.
The first window (November 3, 2026), as a worked example
This page started on the day we ran the routine for the first time, November 3, 2026, so here is what it looked like. The embarrassing part first: we had turned automatic updates off and never run them by hand. Sparks 1–2 had 418 pending updates (273 from the security pocket) and still reported DGX OS 7.5.0; Sparks 3–8 had 225–231 pending (170 security on spark5) and reported 7.6.0. The dry run moved no kernel and no GPU driver package and removed nothing, so this was a normal monthly pass; 226–442 packages upgraded per Spark.
The dry run did turn up one thing worth knowing about: a package called nvidia-spark-mlnx-firmware-manager (6.0.1) flashes the ConnectX-7 network card firmware, 28.45.4028 → 28.50.1002, during apt install. The new firmware takes effect after a reboot, and the updater verifies it on the next boot. That is the card all multi-Spark traffic runs over, so it got the four-first treatment: spark5 alone, then 6–8, then the network tests before we touched Sparks 1–4.
| Sparks 5–8, after the new card firmware | Morning baseline | After |
|---|---|---|
| RDMA bandwidth, median per port | 111.87 Gb/s | 111.87 Gb/s |
| RDMA latency | 3.38 µs | 3.38 µs |
| NCCL all_reduce peak bus bandwidth, 2 Sparks (no memory held / 100 GiB held) | 190.5 / 190.9 Gb/s | 188.9 / 188.3 Gb/s |
| NCCL all_reduce peak bus bandwidth, 4 Sparks (no memory held / 100 GiB held) | 185.3 / 185.6 Gb/s | 186.5 / 186.3 Gb/s |
| NCCL failures | 0 | 0 |
Everything within 1%, which we call no difference. Both model servers came back and answered; the vLLM lane on 5–8 was ready 92 s after start. Downtime per group of four was about 35–40 minutes including the network test. All eight now show DGX OS 7.6.0 packages and 0 pending updates.
One Spark gave us the 20-minute rule. spark8 took 7.5 minutes to shut down: nvidia-persistenced hung in the display driver (nvkms_close in nvidia_modeset) and systemd eventually forced the reboot. Its full reboot took about 15 minutes against about 2 for the others. Counting the boots since, it has happened on 1 of spark8's last 13 boots and on none of Sparks 5–7's. If we had pulled power at minute five we would have turned a slow reboot into an interrupted one. So: wait 20 minutes before assuming a Spark is dead, and do not pull power. We are watching it as an open issue below.
Same day, second window
Two hours after the first pass, a new NVIDIA package showed up: nvidia-spark-initcall-bl 1.0-2 (SW-8). It stops the kernel from starting a MediaTek power-management driver (power_wrap_init) that this platform does not use. NVIDIA's changelog says that driver has been correlated with spontaneous resets while a 4K display is attached. That matches the 7.0.0-1024 reboot loop people reported on the forum with monitors plugged in. Our headless Sparks never had it: 0 GPU firmware timeouts and 0 Xid errors in 38 boots on 1024 across all eight. We took it anyway because it is a stock NVIDIA package, and because the reboot doubled as a test we had not done yet: do our boot-time settings survive a reboot?
Same routine, Sparks 5–8 first. Each Spark got 22 packages, nothing removed, and no kernel or driver change. After every reboot the check script showed every row as ok, the CVE rule and both of its settings were back, a SYN with IP options was dropped over the LAN and over Tailscale, and the first 90 seconds of the kernel log had no Xid, GPU firmware timeout or Oops lines. Every reboot took about 2 minutes, spark8 included. This time we also ran the network tests on Sparks 1–4, which the morning window had skipped.
| After the second window | Sparks 5–8 | Sparks 1–4 |
|---|---|---|
| RDMA bandwidth, median per port | 111.87 Gb/s | 111.87 Gb/s |
| RDMA latency | 2.50 µs (was 3.35 µs) | 2.51 µs |
| NCCL all_reduce peak bus bandwidth, 2 Sparks (no memory held / 100 GiB held) | 188.7 / 179.1 Gb/s | 191.3 / 187.5 Gb/s |
| NCCL all_reduce peak bus bandwidth, 4 Sparks (no memory held / 100 GiB held) | 185.9 / 186.4 Gb/s | 186.4 / 186.5 Gb/s |
| NCCL failures | 0 | 0 |
The surprise was latency. On 7.0.0-1024 our RDMA latency had been 3.35 µs in four separate test runs (3.33–3.39), against 2.50 µs on 7.0.0-1019. With power_wrap_init switched off it is back to 2.50 µs on Sparks 5–8 and 2.51 µs on Sparks 1–4. So that driver was most likely also adding about 0.85 µs to every small RDMA message on 1024. We have not isolated it with an A/B (that one package alone), so treat the cause as likely, not proven. Bandwidth did not change, and we have not yet measured whether model speed did. Fourteen other packages changed in the same window, but none of them touch networking. The 179.1 Gb/s cell is inside the spread that cell has always shown (174.8–192.5 Gb/s). One more lesson: downloading the test image left 12–18 GiB of file cache, so flush the cache before any big allocation test.
ROUTINE-1 Monthly updates (four Sparks first)
- Dry run on every Spark: sudo apt-get -s dist-upgrade | grep -E '^(Inst|Remv)'. Read every Remv line and any linux-image, linux-modules, nvidia-driver or libnvidia line. A kernel or driver move is a separate, tested decision.
- Look for firmware and boot changes inside packages (names with firmware, initcall, grub, kho) and read their install scripts before saying go: nvidia-spark-mlnx-firmware-manager flashes the ConnectX-7 during install. Run sudo fwupdmgr get-updates for system firmware.
- Four Sparks first: stop the model, sudo apt-get dist-upgrade, reboot. Check kernel, driver, both fabric links, clock cap, then an NCCL all_reduce sweep. Restart the model and check it answers.
- Then the other four.
- Treat every reboot as a test that your boot-time settings survive: after it, run spark-check.sh and read the first 90 seconds of the kernel log (journalctl -b -k) for Xid, rpcRecvPoll, Oops.
- Allow 20 minutes per reboot before assuming a Spark is dead, and know who can reach it physically. Do not pull power.
ROUTINE-2 After any change
- bash spark-check.sh --table on every Spark: everything ok or n/a.
- Jumbo ping between every pair on both subnets: ping -c 3 -M do -s 8972 10.0.0.N and 10.0.1.N.
- NCCL all_reduce across sizes, not just perftest: perftest passed 72/72 on a kernel where NCCL failed every run.
ROUTINE-3 After a power cut
- Some Sparks stay off until their power button is pressed (2 of 8 on ours).
- Nothing starts by itself on ours (containers have no restart policy, on purpose): check both fabric links on every Spark before relaunching a multi-Spark model.
Every setting, in detail
One card per setting: the value, why, a check command with its expected output, the apply command, the undo, whether it needs a reboot, and where it came from.
SW-1 Kernel 7.0.0-1024-nvidia
- What we use
- 7.0.0-1024-nvidia via the HWE meta packages; nothing held
- Why
- On our headless Sparks it passed RDMA, NCCL (with and without 100 GiB of GPU memory held), the real 4-Spark model with a bit-identical answer check, and a 6 h soak with 0 resets; since then 0 GPU firmware timeouts or Xid errors in 38 boots across all eight. That is evidence for headless servers only: Sparks with displays attached (especially 4K) reset on 1024 until NVIDIA's SW-8 fix, and we never tested a 4K display or HDMI.
- Applies to
- all
- Check
Expect: 7.0.0-1024-nvidiauname -r
spark-check.sh rows: SW-1, SW-4, SW-5, SW-6- Apply (for humans)
sudo apt-get update && sudo apt-get dist-upgrade # after the dry run in ROUTINE-1- Undo
- Boot the previous kernel from GRUB; keep it installed until the new one has run a week.
- Reboot / downtime
- yes · one reboot
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html
SW-2 GPU driver 580.178.04 (stock)
- What we use
- 580.178.04 from NVIDIA's DGX repo; no .run installers, no other branches
- Why
- Stock driver; the only one with prebuilt modules for 6.17.0-1032, 7.0.0-1019 and 7.0.0-1024. Prebuilt modules pin one exact driver version, so a kernel move is a driver decision.
- Applies to
- all
- Check
Expect: 580.178.04 (both lines)nvidia-smi --query-gpu=driver_version --format=csv,noheader; modinfo -k $(uname -r) -F version nvidia
spark-check.sh rows: SW-2, SW-3- Apply (for humans)
# comes with the DGX OS packages; before rebooting into any kernel:modinfo -k <kernel> -F version nvidia # must print your driver version- Undo
- n/a
- Reboot / downtime
- yes · one reboot
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html
SW-7 kho=off, only on 7.0.0-1019
- What we use
- kho=off on the kernel command line when running 7.0.0-1019; not needed on 7.0.0-1024
- Why
- On 7.0.0-1019 without it, NCCL cannot register memory across Sparks (ibv_reg_mr ... Cannot allocate memory) and multi-Spark models do not start. perftest still passes, so test with NCCL.
- Applies to
- multi-Spark RDMA on 7.0.0-1019
- Check
Expect: kho=off (on 7.0.0-1019 only)grep -o 'kho=off' /proc/cmdline
spark-check.sh rows: SW-7- Apply (for humans)
sudo apt-get install nvidia-spark-grub-kho && sudo update-grub && sudo reboot- Skip if
- you are not on 7.0.0-1019
- Undo
- sudo apt-get remove nvidia-spark-grub-kho && sudo update-grub
- Reboot / downtime
- yes · one reboot
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html#kho
SW-8 NVIDIA's display-reset fix (power_wrap_init blacklisted)
- What we use
- nvidia-spark-initcall-bl 1.0-2: initcall_blacklist=tegra234_cbb_init,power_wrap_init on the kernel command line
- Why
- NVIDIA's package changelog (Nov 1, 2026, urgency high): the MediaTek power_wrap driver drives power management this platform does not use, and enabling it has been correlated with spontaneous resets while a 4K display is attached. This is the fix for the 7.0.0-1024 reboot loops people reported with monitors. Our headless Sparks never showed it; we take it anyway because it is NVIDIA's stock package. Side effect on our Sparks: RDMA latency went from 3.35 µs back to 2.50 µs (the 7.0.0-1019 level) on both groups of four.
- Applies to
- all; most important with a display attached
- Check
Expect: initcall_blacklist=tegra234_cbb_init,power_wrap_initgrep -o 'initcall_blacklist=[^ ]*' /proc/cmdline
spark-check.sh rows: SW-8- Apply (for humans)
sudo apt-get update && sudo apt-get install nvidia-spark-initcall-bl # 1.0-2 or later; runs update-grubsudo reboot- Undo
- sudo apt-get install --allow-downgrades nvidia-spark-initcall-bl=1.0-1 && sudo reboot (1.0-1 is still in NVIDIA's repo; not recommended)
- Reboot / downtime
- yes · one reboot
- Source
- https://forums.developer.nvidia.com/t/dgx-spark-repeatedly-rebooting-after-most-recent-update/387397
FW-1 October 2026 Spark firmware
- What we use
- UEFI 0ACUM028, EC 3.13.7, SoC 2.158.15, USB-C PD 0.5.25 (fwupdmgr / LVFS)
- Why
- Needed for the 0.5 GB display memory option (MEM-1). Also fixes fans stopping in headless mode.
- Applies to
- all
- Check
Expect: contains 0ACUM028sudo dmidecode -s bios-version
spark-check.sh rows: FW-1- Apply (for humans)
sudo fwupdmgr refresh && sudo fwupdmgr upgradesudo reboot # flashes during this reboot; do not cut power- Undo
- No software undo. Flash one Spark first, with someone able to reach it.
- Reboot / downtime
- yes · one reboot (several minutes while it flashes)
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html#now
FW-2 ConnectX-7 firmware 28.50.1002
- What we use
- 28.50.1002, installed by NVIDIA's nvidia-spark-mlnx-firmware-manager 6.0.1 package (was 28.45.4028)
- Why
- Comes with the normal DGX OS updates. The package flashes the network card during apt install; it takes effect after the next reboot and is verified on that boot. On our Sparks: RDMA and NCCL unchanged (within 1%).
- Applies to
- all
- Check
Expect: 28.50.1002sudo mstflint -d 0000:01:00.0 q | grep 'FW Version'
spark-check.sh rows: FW-2- Apply (for humans)
# arrives with: sudo apt-get dist-upgrade (watch for nvidia-spark-mlnx-firmware-manager in the dry run)sudo reboot- Undo
- Save the old image first: cp /opt/nvidia/spark-mlnx-firmware-manager/firmwares/fw-ConnectX7.bin ~/fw-ConnectX7-28.45.4028.bin (before updating); flash it back with mstflint.
- Reboot / downtime
- yes · one reboot
- Source
- https://al-engr.com/dgx-spark-how-we-run-them.html#updates
MEM-1 Display Reserved Memory 0.5 GB
- What we use
- 0.5 GB (default 2 GB). Not Auto, not 4 GB.
- Why
- +1.6 GiB of GPU-claimable memory on every Spark (117.4 → 119.0 GiB, headless). Auto sizes from whatever monitor is attached at boot (1 GB with a 4K monitor). 0.5 GB still shows a text console. Needs FW-1.
- Applies to
- headless or text-console Sparks; desktop users with a 4K screen should use 1 GB or more
- Check
Expect: ends in 00 02 00 00 (512 MiB)sudo od -An -tx1 /sys/firmware/efi/efivars/NvidiaDispFrmStatus-284e19b9-235f-4aab-ae4c-190456d1bd76
spark-check.sh rows: MEM-1, MEM-3- Apply (for humans)
V=/sys/firmware/efi/efivars/NvidiaDispFrmSizeRequest-284e19b9-235f-4aab-ae4c-190456d1bd76sudo chattr -i $V 2>/dev/nullprintf '\x07\x00\x00\x00\x01' | sudo tee $V > /dev/null # last byte: 0=Auto 1=0.5GB 2=1GB 3=2GB 5=4GBsudo reboot- Skip if
- you use the Spark as a desktop or plan to attach a 4K display
- Undo
- Same command with last byte 3 (2 GB), then reboot.
- Reboot / downtime
- yes · one reboot
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html#now
MEM-2 Headless (no desktop)
- What we use
- multi-user.target; remote desktop, printing, Bluetooth, Avahi and ModemManager off
- Why
- About +0.4 GiB of GPU-claimable memory and fewer background processes. NCCL speed did not change (A/B tested).
- Applies to
- servers only
- Check
Expect: multi-user.targetsystemctl get-default
spark-check.sh rows: MEM-2- Apply (for humans)
sudo systemctl set-default multi-user.targetsudo systemctl disable --now gnome-remote-desktop cups cups-browsed cups.socket cups.path bluetooth avahi-daemon avahi-daemon.socket ModemManager- Skip if
- you use the Spark as a desktop
- Undo
- sudo systemctl set-default graphical.target, re-enable the units, reboot
- Reboot / downtime
- yes · one reboot (or isolate)
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html#now
MEM-4 Flush the page cache before each model start
- What we use
- sync; drop_caches before starting a model
- Why
- NVIDIA's unified-memory advice: the file cache otherwise competes with the GPU for the same memory.
- Applies to
- all
- Check
Expect: Cached small right before a model startgrep -E '^(MemAvailable|Cached)' /proc/meminfo
spark-check.sh rows: not checkable from the host by spark-check.sh; use the check command above- Apply (for humans)
sudo sh -c 'sync; echo 3 > /proc/sys/vm/drop_caches'- Undo
- n/a
- Reboot / downtime
- no · none
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html#now
PWR-1 GPU clock cap 2,200 MHz at boot
- What we use
- nvidia-smi -lgc 0,2200 from a systemd unit (reads 2,177-2,190 MHz under load)
- Why
- GB10 has no power-limit setting; the clock is the only power lever. On our rack a long prompt at stock clocks averaged 1,717 W at the wall and tripped a 15 A strip; capped: 1,345 W (-22%) with no loss in decode speed.
- Applies to
- all
- Check
Expect: active; about 2190 MHz under load, max still reads 3003systemctl is-active gb10-clocklock; nvidia-smi --query-gpu=clocks.gr,clocks.max.gr --format=csv
spark-check.sh rows: PWR-1- Apply (for humans)
sudo tee /etc/systemd/system/gb10-clocklock.service > /dev/null <<'EOF' [Unit] Description=GB10 GPU clock cap After=nvidia-persistenced.service Wants=nvidia-persistenced.service [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/nvidia-smi -lgc 0,2200 ExecStop=/usr/bin/nvidia-smi -rgc [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload && sudo systemctl enable --now gb10-clocklock- Skip if
- you need every bit of compute speed and have checked your wall power and cooling
- Undo
- sudo systemctl disable --now gb10-clocklock && sudo nvidia-smi -rgc
- Reboot / downtime
- no · none
- Source
- https://al-engr.com/inference-box.html#power
SEC-1 user.max_user_namespaces = 0
- What we use
- 0, persistent in /etc/sysctl.d/99-no-userns.conf
- Why
- Blocks the first step of a public local root exploit that works on these Ubuntu 24.04 kernels. Docker GPU containers and RoCE still work (tested). Software that needs rootless containers or browser sandboxes will break.
- Applies to
- all
- Check
Expect: 0sysctl -n user.max_user_namespaces
spark-check.sh rows: SEC-1- Apply (for humans)
echo user.max_user_namespaces=0 | sudo tee /etc/sysctl.d/99-no-userns.confsudo sysctl -p /etc/sysctl.d/99-no-userns.conf- Skip if
- you run rootless containers (podman), Flatpak or snaps with sandboxes, or a browser on the Spark
- Undo
- sudo rm /etc/sysctl.d/99-no-userns.conf && sudo sysctl -w user.max_user_namespaces=<previous value>
- Reboot / downtime
- no · none
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html#security
SEC-2 CVE-2026-98432: MPTCP off, request migration off
- What we use
- net.mptcp.enabled = 0, net.ipv4.tcp_migrate_req = 0 in /etc/sysctl.d/99-cve-2026-98432.conf
- Why
- Remote use-after-free in the IPv4 TCP handshake (CVSS 9.8, no login needed). Remote code execution has been reported against MPTCP listeners; Go 1.24+ programs listen over MPTCP by default. Canonical lists linux-nvidia-7.0 on 24.04 as Vulnerable (checked 2026-11-03). Restart MPTCP-listening services after setting it.
- Applies to
- all, until a fixed linux-nvidia-7.0 kernel ships
- Check
Expect: 0 and 0sysctl -n net.mptcp.enabled net.ipv4.tcp_migrate_req
spark-check.sh rows: SEC-2, SEC-3- Apply (for humans)
printf 'net.mptcp.enabled = 0\nnet.ipv4.tcp_migrate_req = 0\n' | sudo tee /etc/sysctl.d/99-cve-2026-98432.confsudo sysctl -p /etc/sysctl.d/99-cve-2026-98432.confsudo systemctl restart dgx-dashboard tailscaled # and any other Go service- Undo
- Remove the file once Canonical marks linux-nvidia-7.0 fixed and you run that kernel.
- Reboot / downtime
- no · none
- Source
- https://ubuntu.com/security/CVE-2026-98432
SEC-4 CVE-2026-98432: drop IPv4 TCP packets carrying IP options
- What we use
- own nftables table, loaded by its own oneshot unit
- Why
- Blocks the trigger described in the upstream fix (commit e3f33b0: the freed memory is the IPv4 options saved from a SYN). Normal traffic never carries IP options; RoCE is UDP and unaffected. Do NOT load it through the stock nftables.service: its default config flushes the whole ruleset, including Docker's rules. Verified on ours: a normal connect still reaches ssh, both model APIs and the metrics port, a connect whose SYN carries a Record-Route option is dropped, over the LAN, the fabric and Tailscale. Mask nftables.service so nobody enables it later.
- Applies to
- all, until a fixed linux-nvidia-7.0 kernel ships
- Check
Expect: ip protocol tcp ip hdrlength != 5 counter ... dropsudo nft list table ip cve_2026_98432
spark-check.sh rows: SEC-4- Apply (for humans)
sudo tee /etc/nft-cve-2026-98432.nft > /dev/null <<'EOF' table ip cve_2026_98432 delete table ip cve_2026_98432 table ip cve_2026_98432 { chain prerouting { type filter hook prerouting priority -300; policy accept; ip protocol tcp ip hdrlength != 5 counter drop } } EOF sudo tee /etc/systemd/system/cve-2026-98432-nft.service > /dev/null <<'EOF' [Unit] Description=CVE-2026-98432 mitigation: drop IPv4 TCP with IP options (own nft table) DefaultDependencies=no Wants=network-pre.target Before=network-pre.target After=local-fs.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/sbin/nft -f /etc/nft-cve-2026-98432.nft ExecStop=/usr/sbin/nft delete table ip cve_2026_98432 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload && sudo systemctl enable --now cve-2026-98432-nft.servicesudo systemctl mask nftables.service- Undo
- sudo systemctl disable --now cve-2026-98432-nft.service
- Reboot / downtime
- no · none
- Source
- https://ubuntu.com/security/CVE-2026-98432
SEC-5 DGX Dashboard auto-update off
- What we use
- /opt/nvidia/dgx-dashboard/settings.json: "update": {"enabled": false}
- Why
- No one-click kernel, driver or firmware change under a running model. The cost: you now have to run updates yourself. We fell 418 updates behind (273 security) before we started doing it monthly (ROUTINE-1). Turn it off only if you will do that.
- Applies to
- anyone who runs updates by hand
- Check
Expect: "enabled": falsecat /opt/nvidia/dgx-dashboard/settings.json
spark-check.sh rows: SEC-5- Apply (for humans)
printf '{\n "update": {\n "enabled": false\n }\n}\n' | sudo tee /opt/nvidia/dgx-dashboard/settings.jsonsudo systemctl restart dgx-dashboard.service- Skip if
- you will not run updates by hand every month
- Undo
- set enabled to true and restart dgx-dashboard
- Reboot / downtime
- no · none
- Source
- https://al-engr.com/testing-dgx-spark-kernels.html#now
NET-1 Fabric: two interfaces, two subnets, MTU 9000, ARP pinned
- What we use
- enp1s0f0np0 = 10.0.0.N/24, enP2p1s0f0np0 = 10.0.1.N/24, MTU 9000 end to end; arp_ignore=1, arp_announce=2, rp_filter=2
- Why
- One 200G cable appears as two interfaces (one per half of the card). At MTU 1500, RDMA between two Sparks ran about 5% slower (185 vs 196 Gb/s).
- Applies to
- multi-Spark
- Check
Expect: 9000 9000; 1 2 2cat /sys/class/net/enp1s0f0np0/mtu /sys/class/net/enP2p1s0f0np0/mtu; sysctl net.ipv4.conf.all.arp_ignore net.ipv4.conf.all.arp_announce net.ipv4.conf.all.rp_filter
spark-check.sh rows: NET-1, NET-2, NET-3- Apply (for humans)
# full netplan file and switch config:https://al-engr.com/networking-dgx-station-sparks-mikrotik-crs804.html- Skip if
- you run a single Spark
- Undo
- n/a
- Reboot / downtime
- no · brief link reset
- Source
- https://al-engr.com/networking-dgx-station-sparks-mikrotik-crs804.html
NET-4 NCCL settings on every Spark
- What we use
- NCCL_IB_HCA=rocep1s0f0,roceP2p1s0f0 NCCL_NET=IB NCCL_SOCKET_IFNAME=enp1s0f0np0 NCCL_IB_ROCE_VERSION_NUM=2 NCCL_IB_GID_INDEX=3 NCCL_PROTO=^LL128 NCCL_MAX_NCHANNELS=8
- Why
- Pin NCCL_SOCKET_IFNAME or NCCL may start over Docker or Tailscale. NCCL_NET=IB makes a broken RDMA path fail loudly instead of falling back to TCP (1.17 GB/s instead of ~23, no error). The last two fix medium messages: 1 MiB all_reduce on 4 Sparks 1.36 -> 11.5 GB/s (found by 0xCS).
- Applies to
- multi-Spark
- Check
Expect: the seven variables aboveenv | grep ^NCCL_ # inside your serving container
spark-check.sh rows: not checkable from the host by spark-check.sh; use the check command above- Apply (for humans)
# pass with -e to docker run / your launcher- Skip if
- you run a single Spark
- Undo
- n/a
- Reboot / downtime
- no · model restart
- Source
- https://al-engr.com/nccl-tuning-4x-dgx-spark-plain-english.html
NET-5 Switch: ECN on, RDMA in its own queue, no PFC
- What we use
- RoCEv2 (UDP 4791) in its own traffic class sharing 50/50 with everything else; ECN on; no PFC
- Why
- Without the RDMA queue an RDMA pile-up starved TCP to 0.002-0.015 Gb/s; with it TCP kept 41-94 Gb/s. ECN cut packet loss into the Station 85%. PFC hurt here.
- Applies to
- switched multi-Spark
- Check
Expect: RDMA counted in queue 3(on the switch) /interface/ethernet/print stats -> tx-queue3-packet rising during RDMA
spark-check.sh rows: not checkable from the host by spark-check.sh; use the check command above- Apply (for humans)
# MikroTik CRS804 commands: https://al-engr.com/networking-dgx-station-sparks-mikrotik-crs804.html- Skip if
- you run a single Spark or no switch
- Undo
- n/a
- Reboot / downtime
- no · forwarding pauses briefly when queues change
- Source
- https://al-engr.com/networking-dgx-station-sparks-mikrotik-crs804.html
What we decided not to do
- Remove snapd or the desktop packages (tens of MB; makes DGX OS updates harder).
- Turn off the DGX Dashboard itself (13 MB; useful). Turn off only its auto-update.
- Change swap, THP or CPU governor (already right on DGX OS).
- Set display memory to 4 GB, or Auto with a monitor attached.
- Use 64K-page kernels.
- Install drivers off the DGX repo (.run installers, other branches).
- Turn on PFC on the switch (it hurt here).
- Load an nftables rule through the stock nftables.service (its config flushes Docker's rules).
Fewer changes is a feature here: every item we leave at the DGX OS default is one less thing to re-check after each monthly update and one less way our Sparks differ from the ones NVIDIA tests.
Open issues we are watching
Things that are not fixed yet, what we do about them in the meantime, and what we are waiting for.
| ID | Issue | Status | Next step |
|---|---|---|---|
| OPEN-1 | CVE-2026-98432 not fixed in linux-nvidia-7.0 | Mitigated (SEC-2, SEC-4). Canonical lists linux-nvidia-7.0 on 24.04 as Vulnerable as of 2026-11-03. Watch: https://ubuntu.com/security/CVE-2026-98432 | When marked fixed: move to that kernel with ROUTINE-1, then remove SEC-2 and SEC-4. |
| OPEN-2 | Rare slow shutdown | 1 of 13 recent reboots on one Spark: nvidia-persistenced stuck in the display driver (nvkms_close); shutdown took 7.5 min, reboot ~15 min. 0 of 13 on three others. Its next restart, the same day, took about 2 minutes. Watch: journalctl -b -1 -k | grep nvkms_close | Wait it out; do not pull power. |
| OPEN-3 | 7.0.0-1024 resets with displays attached | NVIDIA shipped nvidia-spark-initcall-bl 1.0-2 (SW-8). Other 1024 reset reports on the forum involved a self-patched driver module or a different driver (595.99.02); none matched our stock headless setup. Watch: https://forums.developer.nvidia.com/c/accelerated-computing/dgx-spark-gb10/dgx-spark-gb10/721 | Rollback trigger for us: one unexplained reset or GPU firmware timeout on a stock headless Spark. |
| OPEN-4 | Fans ignore CPU heat until about 80 °C; no owner fan control on EC 3.13.7 | Measured on one Spark on 2026-11-04: 20 busy cores, no model, reached 80 °C in 4 s and held near 94 °C with fans about 3,100 rpm; nvidia-smi read 62 °C at most. The ACPI fan setting is accepted and ignored. Partial workaround: cap the Cortex-X925 cores at 2,808 MHz (79.7 °C after 20 min, 16.5% less CPU work). We do not run the cap; our Sparks serve models on the GPU. Watch: https://forums.developer.nvidia.com/t/new-dgx-spark-fans-barely-speed-up-at-high-temps-and-cant-be-adjusted-critical-please-open-fan-control/386805 | When NVIDIA ships an EC with an earlier fan curve or host fan control: rerun the 20-core test and update this section. Do not downgrade the EC or script cooling_device writes. |
How this page stays current
We re-check this page every week against our eight Sparks, using the same read-only check script linked at the top, and against NVIDIA's DGX Spark release notes, known issues and forum advisories, plus Canonical's CVE tracker for the Spark kernel. When something changes we update the settings and the machine-readable copy, add a changelog line here, and bump the Last checked date at the top. If the Last checked date is more than a couple of weeks old, assume we missed a week and check the sources yourself. Start date: November 3, 2026.
- : First version. All eight Sparks updated to DGX OS 7.6.0 packages with ConnectX-7 28.50.1002; CVE-2026-98432 mitigations added.
- : Second window: NVIDIA display-reset fix nvidia-spark-initcall-bl 1.0-2 (SW-8) and security updates on all eight. Mitigations survived the restart; RDMA latency 3.35 to 2.50 µs; network tests now cover both groups.
- : Proofread: MEM-1 gain corrected to +1.6 GiB (was +1.5); latency cause marked likely, not proven; SW-8 undo needs --allow-downgrades; SGLang KV-pool variation noted under Memory.
- : Added CPU-heavy work and the fans (under Power and heat) and OPEN-4: fan response to CPU heat on EC 3.13.7, measured on one Spark, and the X925 clock cap as a partial workaround. Suggested by bellatrix (@0xb3llatrix).
Related posts
- GhettoRak: an 8-node DGX Spark cluster: the build, including the power section that produced the clock cap.
- Testing DGX Spark Kernels: the kernel, driver, memory and security measurements this page's settings rest on.
- Networking DGX Station and DGX Sparks with MikroTik CRS804: the fabric how-to, netplan and switch QoS.
- Why Four DGX Sparks Talk Slowly in the Middle: NCCL Tuning in Plain English: the seven NCCL settings and what each one does.