Skip to main content
0 RPM, 24/7, 2 Years: A Fanless Proxmox Power Node

0 RPM, 24/7, 2 Years: A Fanless Proxmox Power Node

·4467 words·21 mins
Stanislav Cherkasov
Author
Stanislav Cherkasov
{DevOps,DevSecOps,Platform} Engineer
Table of Contents
homelab - This article is part of a series.
Part : This Article

Noise is a reliability problem you can feel.

I wanted nodes that can run 24/7 near living space without the small-jet-engine soundtrack, while still behaving like proper homelab citizens: predictable thermals, real storage, and real networking. Not one hero server. Four small, identical, silent bricks.

This is a review after two years of 24/7 operation: what it is, how I got here, what broke, what I measured, and what I would do again.

The numbers up front:

At a glance
Fans in the case0
Identical nodes4
PL1 CPU power cap35 W
RAM per node96 GB
10G TCP goodput, measured9.27 Gbit/s at MTU 1500
Thunderbolt full duplex7.23 + 7.09 Gbit/s, 14.3 aggregate
Platform power, RAPL PSys spot reading~51 W
Oldest drive (reused from the old box)~25,000 power-on hours

From one old Ryzen box to four identical bricks
#

Before this setup the lab ran on a single aging Ryzen desktop with Proxmox and not enough RAM. Nothing was on fire. I gave the machine away anyway, because I wanted something more reliable, more expandable, and honestly, because a homelab is mostly a license to experiment. I had always been drawn to silent machines: years ago I saw a fully passive case with a solid copper lid and never quite recovered from it.

So the replacement was not a bigger server. It was four identical mini-PCs, bought over a few weeks in spring 2024, configured the same way, running 24/7 with zero fans in the case. The wider cluster grew up gradually around them, and they became its compute backbone: Proxmox on every node, Kubernetes inside VMs, and a spare node that sits half-empty as a manual recovery and rebuild target.

The receipts, because a hardware post without prices is just marketing: the April 2024 order came to about 4,100 zl for two Akasa cases and the first barebone, and May 2024 added two 8 TB QVOs for roughly 3,800 zl. The rest of the fleet followed the same pattern.

The build
#

ComponentPartNotes
BareboneASUS ExpertCenter PN64-E1designed for 24/7 duty; fits Akasa’s custom passive case
CaseAkasa Turing Duo Prothe whole chassis is the heatsink
CPUIntel Core i7-13700H, 14C/20Tcapped on purpose, see the power contract below
RAM2x Crucial 48 GB DDR5-5600 SODIMM96 GB at 5200 MT/s; ASUS lists 2x32 max - solid anyway
System diskSamsung 970 EVO Plus 1TB NVMeESP + LVM root
Data diskCrucial T700 4TB Gen5 NVMe4Kn, LUKS -> ext4; runs at PCIe 4.0 here
Bulk diskSamsung 870 QVO 8TB SATAcheap quiet terabytes
NIConboard Intel I226-V, 2.5GbE-capableused at 1GbE for the management lane
10G laneSonnet Solo 10G SFP+ TB3, Aquantia AQC100Sover Thunderbolt, MikroTik DAC into a CRS317-1G-16S+

Three things make these nodes what they are: built for 24/7, fanless, and with a real 10G uplink despite having no PCIe slot.

Why four small machines instead of one big server
#

A good friend of mine, also a homelabber, loves the opposite approach: big chassis, big sockets, big numbers. I respect it. I run the microservices version of hardware instead, and after two years I am convinced it is the right shape for my lab.

The four boxes are genuinely independent. Three carry the compute; the fourth can idle half-empty or even powered off, existing mostly as a manual recovery and rebuild target (there is no live migration or HA here, and that is deliberate). These four are members of a larger seven-node Proxmox cluster, so losing any one of them, spare included, does not threaten cluster quorum. It still means evacuating workloads manually, because nothing moves VMs for me by design. A big server can be taken down by one bad workload; here the hardware blast radius is a quarter of this fleet at worst.

And a modern mini-PC is not actually small where it counts: 96 GB of RAM and 20 threads per node is a lot of Kubernetes.

Why fanless, and why Akasa
#

A fanless case is not “a quieter PC”. It is a different contract:

  • There is no fan curve to hide mistakes.
  • You cannot brute-force thermals with RPM.
  • The environment (clearance, orientation, ambient temperature) becomes part of the system.

Akasa-style passive cases work because the whole chassis becomes the heatsink. On the Turing Duo Pro the CPU heat moves into the case via a transfer block and heatpipes, and the fin stack does the rest. The result feels more like an appliance than a PC: heavy, solid, silently soaking short bursts. The concept was recommended to me by a friend, and moving a board into the case is genuinely a 15-minute job. My only hiccup was the shop sending a case revision for the wrong PN generation; the Polish store swapped it without drama.

Akasa Turing Duo Pro - exterior
Akasa Turing Duo Pro, the case is the heatsink
Akasa Turing Duo Pro - internal heatpipe layout
Heat moves from the CPU into the chassis via a transfer block and heatpipes

If you want to see how the thermal stack is assembled, this video is a good visual reference:

The thermal pad saga
#

The build lives or dies by thermal contact, and this is where it bit me.

The case wants pads of a specific thickness for the transfer block and the M.2 area, and sourcing exactly the right ones turned out to be surprisingly hard. In my early attempts the NVMe controllers climbed to 80 C, became unresponsive under thermal stress, and disappeared from the bus. When NVMe goes, it goes hard: the device just vanishes mid-write. For a while I could not even tell what was failing.

Two things fixed it:

  1. Laird Tputty 607 dispensable thermal gap filler (6.4 W/mK). The stuff datacenters use instead of guessing pad thicknesses: applied from the tube as a variable-thickness layer rather than a stack of fixed pads. The layer I ended up with might be on the thick side, and the fix held for most of the fleet; current telemetry has just flagged one exception, more on that at the end of this post.
  2. Airflow around the cases. Physics does not negotiate: even a passive case needs the warm air to leave. The nodes sit on a rack shelf with holes drilled through it and large slow fans blowing across the fins. So the setup is not a zero-fan room, it is zero-fan cases with quiet bulk airflow around them, in a separate room on an open rack. The next iteration is a 3D-printed duct coupling a 120/140 mm fan to the fin stack, turbine style: large airflow, no whine.
Four 200 mm Noctua NF-A20 fans laid on the drilled rack shelf before installation
The answer to physics: four 200 mm Noctua NF-A20 on the drilled shelf the cases sit on
The same fans mounted under the shelf, blowing up at the cases
In place under the shelf: huge, slow, quiet, blowing straight at the fins

There is also a kernel-level scar from that era: NVMe power-state transitions were implicated in the dropouts, so APST is disabled outright with nvme_core.default_ps_max_latency_us=0, and it has not eaten a drive since. The two flags next to it are unrelated to the saga: iommu=pt is the passthrough plumbing, and kvm.ignore_msrs=1 is a separate KVM guest-compatibility workaround, unrelated to the NVMe issue.

kvm.ignore_msrs=1 nvme_core.default_ps_max_latency_us=0 iommu=pt

Boring and explicit, the way kernel command lines should be.

The power contract: 35 watts, decided in firmware
#

“Fanless i7-13700H” only works if you decide what the CPU is allowed to burn. Intel’s official numbers for this part are 45 W Processor Base Power and 115 W Maximum Turbo Power. In this case, in this chassis, mine runs with RAPL limits set in the BIOS:

  • PL1 (my sustained cap): 35 W, matching Intel’s listed 35 W Minimum Assured Power for this part
  • PL2 (burst): 82 W

Turbo stays on and the governor stays on performance; the power cap, not a frequency cap, is what shapes behavior. In normal operation (this node carries five VMs) the package draws around 20 W. Under a deliberate 10-minute torture test (stress-ng --cpu 20 --vm 2 --vm-bytes 4G), run on a live homelab node without stopping its normal workloads:

MetricNormal loadUnder stress (10 min)
CPU package temperature46 C56-59 C
CPU package power~20 W35.3 W, pinned at PL1
All-core frequency~2.2 GHz2.55-2.66 GHz
NVMe composite54 C56 C
SFP+ NIC (MAC)61 C61.5 C
SATA SSD50 C50 C
Chart: package power pinned at 35 W while the temperature plateaus under 60 C
Temperature from the node exporter, power from manual RAPL samples taken during the run

The number I care most about: zero new thermal-throttle events through the whole run (the kernel thermal_throttle counters did not move), and the package plateaued at 59 C against a 100 C limit. The CPU was of course limited the entire time, but by power, not by temperature: pinned at the PL1 I chose, which is the contract doing its job. Two minutes after the test it was back at 48 C. Under this workload, the power policy was the active limit, not the case. That is exactly how I want a fanless system to fail: against a number I chose, not against physics. For the record, the instruments: package power is the RAPL energy-counter delta divided by the sampling interval (an on-platform estimate, not a wall meter), temperatures come from sensors, throttle state from /sys/devices/system/cpu/*/thermal_throttle/. The temperature series in the chart, sampled more often than my 90-second manual RAPL readings, caught a brief 76 C spike right at the start; the manual power samples missed the corresponding PL2 burst before RAPL reeled everything back down to the plateau.

The thermal-throttle counters do show historical events from earlier in the node’s life. I like that they are there: they are the fossil record of the thermal pad saga above.

And since the title says power node, the from-the-wall reality: the RAPL PSys domain estimates about 51 W at platform level under normal production load, power-supply losses excluded. The UPS in front of this shelf read roughly 270 W at the same moment for everything it feeds: all four nodes, the four external fans, and the network equipment. Both are spot readings taken while writing this post, not long-term averages; a proper per-node plug-meter measurement is on the follow-up list.

I thought I wanted optics. I needed SFP+
#

The 10G story started with copper. The first iteration used 10GBASE-T, and when I moved it into the big switch, the RJ45 SFP+ module climbed to about 98 C and kicked the switch fans into turbo. In a build whose entire point is silence, that was disqualifying.

I “switched to optics”, or so I told myself ever since. While writing this post I actually looked at what the switch reports on that port:

sfp-connector-type: copper-pigtail
sfp-vendor-part-number: XS+DA0001
rate: 10Gbps, full-duplex, auto-negotiation: done

That is not an optical transceiver. It is a MikroTik DAC: a twinax copper cable with SFP+ ends permanently attached, one meter long. There is no fiber anywhere in this network. SFP+ is a socket, not a medium, and the atlantic driver reporting Port: FIBRE for any SFP+ mode kept my illusion alive.

A MikroTik DAC end seated in an SFP+ cage, blue pull tab and link LED visible
The copper optics up close: a DAC seated in an SFP+ cage, here in one of the cluster’s bigger boxes

Here is the thing though: for short in-rack runs the DAC is not a compromise, it is the better pick. A passive DAC draws essentially zero power and adds no heat, an optical transceiver burns about a watt per end and ages, and the 10GBASE-T module that started this journey burns several watts and doubles as a soldering iron. Everything I wanted from “optics” (cool, stable, nothing to wear out) I actually got from a copper cable with delusions of grandeur. Fiber earns its place at tens of meters and beyond; my runs are one meter.

Thunderbolt as a PCIe slot
#

These mini-PCs have no PCIe slot, but they have Thunderbolt with 40 Gb/s behind it. So the 10G NIC lives outside the case:

flowchart LR
subgraph NUC["one fanless node"]
E0["Intel I226-V
onboard 1G"] TB["Thunderbolt / USB4 port"] end TB --> SON["Sonnet Solo 10G
TB3-to-SFP+ adapter"] SON -->|"MikroTik DAC, 1 m"| SW["MikroTik CRS317-1G-16S+
16x SFP+"] E0 --> MGMT["1G switch
management lane"]

This is what that chain looks like in the flesh, dust included:

All four nodes on the shelf, Sonnet adapters zip-tied on top, DACs attached
The whole 10G lane in one photo: Sonnet adapters and DACs with their blue pull tabs

The Sonnet adapter carries an Aquantia AQC100S and is itself passively cooled, which fits the build philosophy nicely. boltctl shows the chain running at the full 2x20 Gb/s, with the device authorized under bolt’s iommu policy - that is Thunderbolt DMA protection, a separate knob from the kernel’s iommu=pt earlier:

* Sonnet Solo 10G SFP+ Thunderbolt 3 Edition
  type: peripheral
  generation: Thunderbolt 3
  status: authorized
  rx speed: 40 Gb/s = 2 lanes * 20 Gb/s
  tx speed: 40 Gb/s = 2 lanes * 20 Gb/s
  policy: iommu

Operationally the whole Thunderbolt story reduced to two boring pieces of configuration: the bolt daemon with the device enrolled once, and a udev rule that re-attaches the NIC to its bridge whenever the adapter (re)appears, so a power blip or a physically reattached Thunderbolt adapter heals itself without me. Interface naming is pinned to classic ethX via the kernel command line so the rule always matches. During the current five-day uptime the kernel log shows one link-up at boot and then silence. That is consistent with the longer operational history of this lane, although the current log itself only covers this boot.

The onboard I226-V stays as the second lane: cluster management traffic on 1G, completely independent from the 10G data path. Kubernetes never touches it.

The 10G numbers, measured on the live setup
#

Everything below was measured on the live homelab setup: both nodes were carrying their normal Proxmox and Kubernetes load at the time, one of them running five VMs at a load average around 2. I did not quiesce anything on purpose. A lab-clean benchmark tells you what the link can do once; a test on the live system tells you how it behaves under its real workload.

Tooling is deliberately boring: iperf3 from the Debian repos (3.18 on Proxmox VE 9), one node as server, one as client:

# server (node A), bound to the 10G address on purpose
iperf3 -s -B <node-a-10g-ip>

# client (node B): four runs, each answers a different question
iperf3 -c <node-a-10g-ip> -t 30 -O 3           # 1: a single TCP stream
iperf3 -c <node-a-10g-ip> -t 30 -O 3 -P 4      # 2: aggregate ceiling
iperf3 -c <node-a-10g-ip> -t 30 -O 3 -P 4 -R   # 3: reverse direction
iperf3 -c <node-a-10g-ip> -t 30 -O 3 --bidir   # 4: both directions at once

Why exactly this shape and not another:

  • Bind to the 10G addresses. These nodes also have a 1G management interface. If you let the tools pick a route, you can spend an evening benchmarking the wrong NIC. -B on the server plus the 10G address on the client removes the ambiguity.
  • -t 30 -O 3. Thirty seconds is long enough to catch drift; the first three seconds are omitted so TCP slow-start does not pollute the average.
  • One stream first. A single TCP connection is what a real file copy gets, and it is usually core-bound below line rate. Reporting only the multi-stream number would be marketing.
  • Four streams. The aggregate ceiling of the link.
  • Reverse (-R). NIC, driver, and IRQ behavior are not symmetric. Testing one direction and assuming the other is a classic way to miss a problem.
  • --bidir. For this build it answers the one question everyone asks: does the Thunderbolt chain choke when both 10G directions run at once?
  • Watch Retr, not just the bitrate. Retransmits on a clean link should be around zero; they tell you about path quality long before throughput drops.
  • MTU is 1500. No jumbo frames on this network, so the honest TCP goodput ceiling is about 9.4 Gbit/s, and every result below is judged against that, not against the “10G” printed on the box.
  • A second terminal runs watch sensors. On a passively cooled node a network stress test is also a thermal test: the SFP+ cage and the NIC are part of the thermal budget.

The results, on the live setup:

RunResultRetransmits
1 stream7.72 Gbit/s0
4 streams9.27 Gbit/s0
4 streams, reverse9.26 Gbit/s1384
bidir, both directions at once7.23 + 7.09 = 14.3 Gbit/s0

Reading it:

  • 9.27 Gbit/s of TCP goodput with zero retransmits is close to the practical ceiling for a 10G link at standard MTU (iperf3 measures application throughput, not wire rate). The SFP+-over-Thunderbolt path needed no throughput tuning in this test.
  • A single stream lands at 7.7 Gbit/s. That is normal single-flow behavior, not a defect of the adapter.
  • The reverse direction shows 1,384 retransmitted TCP segments over a 32 GB transfer, at identical throughput. That is what “tested on a busy live node” looks like; TCP absorbs it silently, and I prefer publishing this number over a sterile one.
  • The bidir run is the number I actually built this for: 7.23 plus 7.09 Gbit/s simultaneously through one Thunderbolt 3 link. The 40 Gb/s chain was not the bottleneck at the measured 14.3 Gbit/s aggregate load.
  • Thermals during the duplex run: SFP+ NIC at 63 C (from roughly 57-60 idle), CPU package at 64 C, NVMe under 60 C. No throttling, comfortable margins, still zero fans in the case.

Storage: three tiers in a shoebox
#

This node is storage-heavy for a mini-PC because it is meant to do work, not just host dashboards:

NAME      MODEL                         SIZE  ROLE
nvme_a    Samsung 970 EVO Plus 1TB    931.5G  system: ESP + LVM root
nvme_b    Crucial T700 4TB (Gen5)       3.6T  data: LUKS -> ext4
sda       Samsung 870 QVO 8TB           7.3T  bulk SATA

Two details worth calling out:

  • The Gen5 drive runs at Gen4. The T700 is a PCIe 5.0 SSD, but this platform’s M.2 lanes are PCIe 4.0: lspci reports LnkCap: 32GT/s against LnkSta: 16GT/s (downgraded), x4. I bought it for the 4Kn path and the price per terabyte, not for Gen5 sequential bragging rights, so nothing of value was lost.
  • The Gen5 drive is formatted 4Kn (4096-byte LBA: lsblk reports LOG-SEC/PHY-SEC 4096 both for the device and for the dm-crypt mapper above it, so the 4Kn geometry survives the whole stack, not just 4K filesystem blocks), while the system drive is classic 512B. That is intentional: I wanted to run the 4Kn path end to end instead of discovering its quirks by accident later.
  • NVMe enumeration is not stable across boots. Which drive is nvme0n1 and which is nvme1n1 has flipped on this node between kernels. Everything that matters references filesystems by UUID, and so should you.

The SMART counters double as this post’s receipts for the “24/7, 2 years” claim. The SATA drive was reused from the previous Ryzen box and now shows about 25,000 power-on hours; the drives bought with the nodes agree with the timeline: the Gen5 drive about 19,700 hours with 76 TB of host writes and a Percentage Used of 8% in NVMe SMART, the system drive about 14,800 hours at 2%. The fleet has been awake this whole time, and after the pad saga was fixed, none of the drives have logged a single media error.

Proxmox first, Kubernetes second
#

All four nodes run Proxmox, and Kubernetes lives strictly inside VMs. I never wanted a single OS to own the hardware.

Part of it is philosophy: these are consumer boxes with no BMC, no IPMI, no iLO. A hypervisor is what makes the workloads recoverable and rebuildable, even without out-of-band management. Set up once, they are easy to operate and easy to rebuild: when something breaks, it usually breaks inside a disposable VM while the host stays reachable. Rebuilding a node from scratch is a non-event, backed by Proxmox Backup Server and configuration management.

Part of it is what the layer buys me beyond Kubernetes: whole environments are declared in Terraform and stood up or torn down as VM sets on a software-defined network, the permanent one is wired through Argo CD, one node moonlights with a passed-through iGPU for experiments, and the odd Windows VM shows up when something needs testing. The lab currently runs multiple Kubernetes environments this way; the busiest one holds around 244 pods.

Deliberate simplicity elsewhere: no live migration, no HA auto-restart, no fencing, default quorum. The one carefully engineered failure mode is power: a UPS feeds these nodes, one of them acts as the NUT master, and on mains loss the fleet shuts itself down cleanly, in priority order. Tested repeatedly; the shutdown sequence has been reliable so far.

VM storage is local rather than ZFS- or Ceph-backed: the data tier is LUKS to ext4, and bulk shares are served over NFS and Samba. I experimented with ZFS and Ceph and walked away from both for this fleet: the memory tax and the disk churn were not buying me anything at this scale. A dedicated storage node on the 10G network is the plan for the day that stops being true.

96 GB of RAM and no regrets
#

Every node was maxed out on day one: 2x48 GB. The philosophy came from an old life with AIX on Power, where machines shipped fully populated and you licensed what you used. Identical, fully loaded nodes mean no DIMM matching, no timing archaeology, no “which box has the spare slot” spreadsheet, ever.

It was also a market bet that aged embarrassingly well: the kit cost about 300 EUR per node then, and the same kit is roughly triple that today.

And the memory is not sitting idle. Utilization sits between 45% and 57% across the fleet, and the lesson of two years is blunt: in this architecture RAM is the resource that matters, then disks and network. The CPU is the thing I ration hardest (35 W!) and miss least. When something does saturate, it is usually the 10G lane during backups or when I am stress-testing AI agents, which is exactly why 40G and 100G MikroTik hardware keeps appearing in my browser tabs.

Operational notes
#

A passively cooled node still needs operations discipline:

  • Clearance matters. Give the case room; the chassis is the heatsink.
  • Monitor throttling, do not infer it. The kernel throttle counters and RAPL power are the truth; “it feels slower” is not.
  • Treat the SFP+ cage as part of the thermal budget. Even a cool DAC lives next to a NIC running at 60 C.
  • Treat Thunderbolt as a bus. Enrolled device, IOMMU policy, self-healing udev rule, and then leave it alone.
  • Watch the drives, not just the CPU. NVMe temperature and media errors are the canaries; media errors have stayed at zero since the pad fix, and the temperature canary is chirping on one node right now (see the table below).

The fleet, by the numbers
#

Instead of claiming that all four nodes are boringly stable, here is the current fleet snapshot pulled from Prometheus while writing this post (last 15 days of retention, as of 30 July 2026; thermal counters are shown since the last boot, which was a planned kernel update five days earlier; eth1 is the 10G Thunderbolt lane):

Metricnode Anode Bnode Cnode D
Uptime since planned reboot5.4 d5.4 d5.4 d5.4 d
CPU package thermal-status transitions since last boot5900146,298
Max CPU package temperature, 15 d91 C83 C83 C95 C
Max NVMe temperature, 15 d64 C71 C78 C77 C
Max AQC100S NIC temperature, 15 d67 C68 C67 C67 C
eth1 carrier changes, 15 d0000
eth1 RX / TX errors, 15 d0 / 00 / 00 / 00 / 0
eth1 RX drops, 15 d000562
NVMe media errors, lifetime0000
NVMe Percentage Used8%12%10%8%
Average RAM used, 15 d51%57%46%45%

A few notes on the table. Each node has one CPU package, and the package counter was read once per node, never summed across logical CPUs: the kernel mirrors that counter to every CPU, so summing cpu*/ values inflates it by the core count. The NIC temperature is the AQC100S sensor on the Sonnet adapter, not a direct measurement of the SFP+ cage. And the 15-day CPU maxima include short PL2 bursts and real workload spikes, which is why they sit far above the steady-state 56-59 C of the controlled stress test earlier: that test shows where the temperature settles once PL1 takes over.

Three nodes looked ordinary. One did not. Node D showed an abnormal number of CPU package thermal-status transitions since its last reboot, together with an elevated NVMe temperature profile and a small number of interface drops. I am not calling this a failed thermal interface yet; the raw counters, kernel logs and sensors need to be checked first. But the monitoring did exactly what it was supposed to do: it found a problem I would otherwise have missed.

The next maintenance action is to inspect the thermal stack and airflow on that node.

Two years in: what I would repeat
#

  • Fanless is not a style choice. It is a constraint that forces correctness: thermal contact, power limits, and airflow all have to be decided, not defaulted.
  • Small identical nodes beat one big server for the way I actually operate: blast radius, spare capacity, and guilt-free rebuilds.
  • Cap the CPU yourself. A 35 W contract you chose is better than a 100 C limit physics chooses for you.
  • SFP+ over Thunderbolt is a legitimate way to give a mini-PC a real uplink: 9.27 Gbit/s of TCP goodput one way, 14.3 Gbit/s aggregate in full duplex, and a kernel log that only ever mentions the link once per boot.
  • Check what is actually in your SFP+ cage. I ran “optics” for over a year before learning it was a copper cable, and the copper cable was the right choice all along.
  • Measure on the live system. Sterile benchmarks flatter; production numbers you can trust.

Appendix: inventory commands
#

Selected inventory and verification commands, sanitized:

sudo dmidecode -t system; sudo dmidecode -t memory
lscpu
lsblk -e7 -o NAME,MODEL,SIZE,TYPE,FSTYPE,MOUNTPOINTS,TRAN,LOG-SEC,PHY-SEC
# LOG-SEC/PHY-SEC 4096 = real 4Kn block-device geometry, not just 4K filesystem blocks
sudo smartctl -a /dev/nvme0n1   # and friends
lspci -nnk
sudo lspci -vv -s <nvme-addr>   # LnkCap vs LnkSta: how the Gen5 drive negotiates Gen4
sudo boltctl list
sensors
sudo ethtool eth1
sudo ethtool -S eth1            # per-queue/error counters behind the drops row
ip -s link                      # errors and drops as the kernel counts them
grep . /sys/class/powercap/intel-rapl:0/constraint_*_power_limit_uw
cat /sys/devices/system/cpu/cpu0/thermal_throttle/package_throttle_count
# read one logical CPU per package; do not sum cpu*/ values -
# the kernel mirrors the package counter to every CPU
homelab - This article is part of a series.
Part : This Article

Related