I have two 128 GB unified-memory machines on my desk. Day job gear, not mine. One is an ASUS Ascent GX10 — an NVIDIA GB10 Grace Blackwell appliance half the size of a hardback book. The other is an HP ZBook Ultra G1a, a 14" mobile workstation running AMD’s Ryzen AI MAX+ PRO 395 (“Strix Halo”). Both hold an 80B coding model entirely in memory. How do they compare for agentic coding?
I wanted very badly for the laptop to be good enough. Partly for selfish reasons — a laptop that serves its own coding agent on an airplane is a genuinely different life than a laptop that phones home to a box in the office! But my experience these past few months made me wonder if I was using it incorrectly.
Both of these hold the same 80B model in memory. The little one serves it 1.71× faster.
So I actually tested it. 27 trials, one frozen task, one frozen grading suite, one variable. The repo and results are here.
The short version: the code they produce is indistinguishable. The GB10 is 1.71× faster per token. But the gap that actually matters isn’t speed at all — it’s whether the thing finishes without you. The laptop burns enormously more turns getting to the same answer, and far more often never declares itself done at all.
That last part is the finding I didn’t expect, and it’s the one that matters. Waiting is an annoyance. Coming back to a job that quit — or that has been sitting there for an hour waiting to ask you a question — is the thing that actually costs you the afternoon.
Why I Bothered
Agentic coding is, by a wide margin, the most token-hungry thing I do. Chat is nothing next to it. An agent that reads files, runs a build, reads the failure, edits, and runs it again burns tokens in a way that makes an interactive conversation look free — and it does it unsupervised, at machine speed, while you go get coffee. Or sleep.
Back in May I wrote that AI inference costs are the wake-up call for 2026 and 2027 — Anthropic ending fixed enterprise pricing, Copilot going usage-based, and every budget built on fixed-fee assumptions quietly becoming wrong. I closed that post with a section called “The Case for Local Inference” and a promise to dig into it later.
This is me digging into it. Hi. It took a while.
In July I followed that up with the vocabulary I think makes this land in a budget meeting: tokens should be NRE, not COGS. Spend in the COGS column and you buy one cut, at the same price, forever. Spend in the NRE column and you buy a jig — expensive once, then nearly free.
Local inference is the most literal version of that argument I know. A box you bought is NRE. A cloud token is COGS, every single time, forever. Well, actually it’s CAPEX but let’s not get into the details of accounting. It’s the same thing for the point I’m making.
So I went and looked at that number from my results again: 1567 turns instead of 86.
On a metered endpoint, that’s not a slow build. That’s an eighteen-times bill for the identical deliverable, and you might not notice until the invoice shows up. On hardware you already own, it’s just wall clock on a machine that was sitting there anyway.
Which reframes the whole comparison. A box that’s 1.71× slower per token is a completely different proposition when its tokens are free at the margin. Slow and owned beats fast and metered at some exchange rate.
But “free at the margin” is doing a lot of work in that sentence, and I don’t want to slide past it. Wall clock is not free. Moving the meter off dollars doesn’t delete the cost — it changes the currency. Now you’re paying in whether anyone actually reaches for the thing instead of tabbing back to the cloud. Those are the bills local inference sends you, and they’re denominated in exactly the thing these two machines differ on.
So the speed question doesn’t go away when you own the hardware. It’s the only question left. Which is the entire reason for everything below.
Two Boxes, One Question
The question isn’t “which one wins a synthetic benchmark.” I don’t care. The question is: which one actually takes a specified project from requirements to a tested binary — unattended?
And I want to be precise about that word, because waiting is the least of it. Sitting there watching tokens crawl out is a minor irritation. The thing that actually wrecks the afternoon is an agent that doesn’t finish: it either fails somewhere in the middle, or it stops and quietly waits on a question while you’re off doing something else. Either way you come back an hour later to a process that has been parked since about four minutes after you walked away.
That’s the real currency. Not tokens per second. Whether you can kick it off, leave, and come back to a result instead of a prompt.
| ASUS Ascent GX10 | HP ZBook Ultra G1a 14" | |
|---|---|---|
| Silicon | NVIDIA GB10 Grace Blackwell | AMD Ryzen AI MAX+ PRO 395 |
| Accelerator | Integrated Blackwell | Radeon 8060S, 40 CU, gfx1151 |
| Backend | CUDA 13.0 | ROCm 7.2.1 |
| Memory | 128 GB unified | 128 GB unified, 92.5 GiB GPU-visible |
| Form factor | Desk appliance, mains powered | Fits in a backpack |
Here’s why the answer isn’t obvious, and why this was worth doing properly instead of just eyeballing it.
Both boxes serve bit-identical weights. Same model (qwen3-coder-next, 79.7B total parameters with about 3B active — 10 of 512 experts), same digest, same quantization, same 131072 context, same KV cache type, same Ollama version. So the honest prior on output quality is no difference at all. If one box reliably wrote better code than the other, that wouldn’t be capability — it would be a numerical divergence between the CUDA and ROCm kernels. That’s a bug report, not a verdict.
The expected difference was speed. And specifically, whether that speed difference compounds across the dozens of turns an agentic build actually consumes.
Spoiler: it compounds. Not in the way I predicted.
First, a Big Fat Caveat
This is my first serious attempt at building a structured comparison like this, and I want to be honest about what that means: the premises are quite likely flawed in ways I haven’t spotted yet.
I’m a software guy who has been shipping systems for a long time. I am not a benchmarking researcher. I built this harness from scratch over a few days, and along the way I found five separate bugs in my own test rig that would each have silently corrupted the results. Five that I found. I have no particular reason to believe there isn’t a sixth.
The worst one is instructive: I had pinned the model’s context window to 131072 on the GX10 but not on the ZBook. Both machines advertise 262144 while actually serving 131072, so my agent was over-packing every request to the laptop by 2× — an uncontrolled asymmetry in the exact variable I was trying to measure. I caught it by accident. If I hadn’t, I’d have published a much more dramatic and completely wrong number.
In fairness to my own process, the other four surfaced because I built this thing spec-first using Superpowers — a frozen design spec, an implementation plan derived from it, and a code review at every step, with the review diffs committed alongside the code. That discipline is the only reason a harness written in a few days has its own paper trail of what it was supposed to do, which is exactly what you need to notice that it isn’t doing that. Superpowers has changed how I work at least as much as the agent has, and it’s getting its own post too.
So read everything below as “this is what one guy measured on his own gear with a harness he wrote himself,” not as a review. The whole thing is out there — requirements, grading suite, harness, and a findings doc that keeps my retracted conclusions on the record next to the corrected ones — precisely so somebody can tell me where I’m wrong.
When the Anecdotes and the Data Disagree
There’s a Bezos line I keep coming back to:
“The thing I have noticed is when the anecdotes and the data disagree, the anecdotes are usually right. There’s something wrong with the way you are measuring it.”
I love that quote because it inverts the usual engineering reflex. We’re trained to trust the instrument over the human. Bezos is saying: no, when your careful measurement contradicts what people are actually telling you they experience, your measurement is the suspect.
Here’s why I bring it up. In my case, the anecdotes and the data agree. Everything I measured over 27 trials matches what my hands had already told me over weeks of just… using these machines. The laptop feels slower. The laptop feels like it thrashes. The desk box feels like it gets to the point.
That agreement doesn’t make the data right. But it’s the best gut check available to me on a first attempt at a test like this, and it’s the thing that let me publish it instead of throwing it away. If my careful little benchmark had told me the laptop was faster, I’d have gone looking for the bug — and per Bezos, I’d have been correct to.
How I Tested It
Five decisions did most of the work here.
One agent, one frozen configuration, every single trial. Every trial on both machines was driven by oh-my-pi — omp (omp.sh). Same binary, same version, and one frozen configuration overlay loaded before the host routing on all 27 runs.
I want to dwell on that config for a second, because it’s doing more work than “same settings” suggests. What it mostly does is turn things off: memories, autolearn, hindsight mental models, context promotion, branch summaries, recap, prewalk, advisor, web search. Every one of those is a feature I want in daily use, and every one of them would have quietly wrecked this experiment — because an agent that remembers trial N-1 is not giving you 27 independent trials, it’s giving you one trial and 26 echoes. Fresh throwaway profile per trial, so nothing leaks forward. The loop guards stayed on deliberately, since a repetition loop is a real failure mode I wanted to measure rather than prevent.
If the agent’s configuration had drifted between the two hosts, none of the numbers in this post would mean anything — I’d be comparing prompts, not machines. omp is my new shiny toy and much, much better than claude code for local inference, and it deserves its own post rather than a paragraph. It’s coming.
Freeze the task. The agent implements pngdec, a small Go CLI that reports PNG chunk structure as JSON — with specified exit codes, partial output on malformed input, and byte-offset error messages. It’s written down in a requirements document that never changed between trials. Small enough to finish, precise enough to score by machine.
Freeze the grader, and never show it to the agent. Correctness is decided by 32 acceptance test cases I wrote from the requirements. Every trial’s binary gets run against that identical suite. This is the piece I’d tell anyone else to do first, because a metric that depends on me reading diffs cannot be compared across dozens of trials. I’d just be grading my own mood.
Hold everything else constant. Same driver machine, same agent binary, same model digest, same Ollama version, same server tuning, same prompt, fresh git workspace per trial. A preflight check verifies all of it before every batch and aborts on any mismatch. And critically: neither box drives its own trials. A third machine runs the agent for both, so neither gains from local socket latency or loses CPU to the agent process.
Treat cloud contamination as fatal. A single turn silently served by Ollama Cloud would score the wrong machine entirely. Model fallback is disabled and every trial’s turns get verified against the intended provider. Any contaminated trial is voided, not trusted.
You do use a fresh workspace per trial, right? I didn’t, at first. Don’t be me.
Finding One: The Code Is Indistinguishable
| host | trials | perfect 32/32 | median score |
|---|---|---|---|
| GX10 (GB10) | 19 | 3 | 0.84 |
| ZBook (Strix) | 8 | 2 | 0.84 |
Identical medians. Both hosts range from 7/32 to 32/32 depending on the run. That spread is sampling noise, not hardware.
This is a null result, and it’s the whole foundation. The two boxes serve bit-identical weights, so “no quality difference” was the honest prior going in. Getting it is what makes the speed numbers trustworthy — if quality had diverged, I’d have had a kernel bug to chase instead of a comparison to report.
And here’s the fun part: I did prove the two backends compute different numbers. Identical frozen prompt, 1003 tokens, greedy decoding, each host perfectly reproducible with itself — and the first generated token differs. The GB10 says " P" (heading toward “PAX sparse file headers”), Strix says " GNU" (heading toward “GNU sparse file headers”). Both are plausible continuations. It’s an argmax flip on a near-tie, exactly what floating-point non-associativity and different reduction orders guarantee you’ll get across two backends.
Real divergence. Zero measurable effect on final quality. Sometimes the interesting bug is the one that doesn’t matter.
Finding Two: 1.71× on Decode — and Why That Number Surprised Me
Decode rate, scraped from both servers’ logs during the real workload rather than from a synthetic probe. About ten thousand samples:
| host | samples | min | median | max |
|---|---|---|---|---|
| GX10 | 4385 | 34.6 | 44.5 | 61.1 |
| ZBook | 6085 | 19.2 | 26.0 | 46.9 |
26 tokens/sec sustained on an 80B model, from a 14" laptop, on battery-capable silicon. Stop and appreciate that for a second. That number would have been science fiction one year ago. Sparse activation is why it’s possible at all — only ~3B of those 80B parameters fire per token.
But 1.71× bugged me, and here’s why. Decode is memory-bandwidth-bound, and on paper these two machines have nearly the same memory bus: the GB10 is around 273 GB/s and Strix Halo is around 256 GB/s. That’s about 7% apart. Yet I measured decode 71% apart.
If decode were purely bandwidth-bound, that gap should have been small. It wasn’t. Something is eating the difference, and my money — and I want to be clear this is a hypothesis I did not measure, not a finding — is on the software stack. CUDA’s kernels for this shape of work have had years of tuning that ROCm on gfx1151 simply hasn’t had yet. Strix Halo is bleeding-edge silicon; I’ve already written about what that costs you on Linux.
If someone wants to prove me wrong there, please do. I’d genuinely rather learn than be right.
All of that is decode. There’s a second half to inference, and for agentic work it may matter more.
Generating text happens in two distinct phases. Prefill is the model reading — it ingests the entire prompt and does the math across all of it before emitting a single character. Every input token can be crunched in parallel, so prefill is compute-bound: a big pile of matrix multiplication where raw arithmetic throughput wins. Decode is the model writing — one token at a time, each one depending on the one before it, so it can’t be parallelized and instead has to stream the weights through memory for every single token. That’s why decode is bandwidth-bound and prefill isn’t.
Which explains how the same two machines can be 1.71× apart on one phase and nearly 4× apart on the other. Blackwell has vastly more arithmetic to bring to bear. It just can’t use most of it when the bottleneck is the memory bus.
Prefill is what you actually experience as time to first token — the dead air after you hit enter, before anything shows up on screen.
And here’s why that lands harder on an agent than on a chat. Every turn re-sends the whole conversation. The agent reads a file, runs a build, pastes in the error output, edits, runs it again — context grows monotonically all day long. A good server reuses the cached work for the part of the prefix that hasn’t changed, which helps a lot. But anything that rewrites the context throws that away, and when you’re filling a 131k window, compaction eventually does exactly that. Then you pay full price again. Multiply by 86 turns. Or 1567.
Decode speed sets how fast you watch it type. Prefill speed sets how long you wait before it starts — over and over and over.
Prefill favors the GB10 much more heavily: 2.8× at 32k context, 3.8× at 90k. Those cells have n=1, so don’t quote them as settled. But time-to-first-token at 90k context was 68 seconds on the GB10 versus 256 seconds on the ZBook. Four minutes of nothing, before the first character. That one you feel in your chest.
Finding Three: The Real Cost Isn’t Speed — It’s Whether It Finishes
This is the part I did not see coming.
Restricting to trials where the agent actually stopped on its own — the only runs with a meaningful end-to-end time, since a capped run’s duration is just the cap:
| host | n | wall minutes | turns |
|---|---|---|---|
| GX10 | 7 | 10.6 – 60.9, median 29.2 | 47 – 165, median 86 |
| ZBook | 1 | 182.3 | 1567 |
Six times the wall clock. Eighteen times the turns. Against a decode ratio of 1.71×.
The gap is not throughput. The gap is thrashing. The ZBook got to the same destination — that 182-minute run scored a perfect 32/32, better than most of the GB10’s runs — but it needed 1567 turns where the GB10 typically needs 86. Its final six tool calls were byte-identical to each other. It spent a huge share of those turns in a loop before it escaped and finished.
That’s consistent with the logit divergence I confirmed earlier: same weights, same final answer, but the near-tie flips route Strix down longer, loopier paths to get there. It doesn’t change where the model lands. It appears to change how much wandering it does on the way.
Caveat, and it’s a large one: n=1. That’s the only ZBook run in existence that terminated on its own. Every other one hit my time cap. So the ~6× figure is the weakest claim in this entire post, and I’d bet against the specific multiplier while betting for the direction.
Which brings me to the number that actually answers the unattended question. How often did the agent stop on its own at all?
| host | ran to completion by itself |
|---|---|
| GX10 | 7 of 17 — 41% |
| ZBook | 1 of 6 |
Now, I’m about to spend a whole section explaining why that metric is a lousy measure of capability, and I stand by that — it says nothing about whether the code came out any good. But it is the direct, literal measure of the thing I care about most: did this thing run to the end without me in the loop?
And on that measure, look at the GX10’s number again. 41%. The machine I’m going to end up recommending failed to finish on its own more often than it finished. Neither of these boxes is something you can currently start and walk away from on a task this size. The GX10 is just less bad at it.
That’s the finding I’d most want a skeptic to hold me to. The speed gap is real but survivable. The “will it finish” gap is the one that decides whether any of this is usable, and both machines are worse at it than I’d like — which is a statement about the model and the agent as much as about the silicon.
And here’s the part I only really understood after staring at the logs: a timeout is not a separate failure mode. It’s an agent asking for help in the only language it has left.
Every trial that hit the cap had already built a working tree — source, tests, a Makefile, a compiled binary. It then got stuck during verification and, rather than stopping, re-issued the same command again and again. In the failed runs the last six tool calls collapse to a single distinct command. That is not a machine being slow. That’s a machine that is confused, and has no way to say so.
Approvals were off, so it couldn’t stop and ask me anything. Which means “needs a human” and “spins until the clock kills it” are the same event wearing different clothes. If it’s just spinning, it needs help. So that timeout column is really a proxy for how often a run needed guidance and had no way to request it — and on the GX10, that proxy reads 59%.
86 turns versus 1567. Same destination. The gap isn't speed — it's wandering.
What I Got Wrong (Twice)
My first correctness metric checked that the agent exited cleanly with a successful build. It never checked whether the tests passed.
Read alone, that metric said one box works and the other never does. Then I scored the frozen suite and found out how wrong I was, in both directions at once:
- One ZBook run recorded as a failure (hit the time cap) had already written perfect 32/32 code. It just never declared itself done.
- One recorded as a success had failing tests and was repeating the same command when it stopped. It declared victory mid-loop.
Termination is not capability. I fell into that trap, published the wrong conclusion internally, corrected it, and then very nearly fell into it again. My findings doc now keeps the wrong version on the record right next to the right one, because I don’t trust myself not to reach for the easy metric a third time.
Two more that cost me real time:
A shorter time cap manufactures failures. I tightened my cap from 90 minutes to 70 to save wall clock. The GB10’s self-termination rate collapsed from 5/6 to 2/11. Capped runs frequently contain correct code, so a tight cap doesn’t save you time — it throws away results you already paid for.
Higher precision made both machines worse. This one needs a definition first, because the KV cache is one of those things everybody running local models has an opinion about and not everybody can define.
To generate the next token, a model attends to every token that came before it. Recomputing all of that from scratch on each new token would be brutal, so it keeps the intermediate key and value vectors for every token it has already processed and reuses them. That’s the KV cache. It is pure speed — without it, generation slows to a crawl as the conversation grows — and you pay for it in memory that grows right along with your context. At the 131072 context I served, mine measured about 1.6 GB, sitting alongside 48 GiB of weights. On a box where memory is the whole product, that’s not a rounding error.
The knob is how precisely you store those vectors. q8_0 quantizes them to 8 bits and halves the footprint. f16 keeps full 16-bit floats — twice the memory, no rounding. And that rounding is the interesting part: quantizing the KV cache puts approximation error directly inside the attention mechanism, which is exactly the kind of thing you’d suspect if one of your two machines were behaving strangely. Hence the experiment.
So I switched from q8_0 to f16, expecting the ZBook’s looping to ease. Both hosts went to 0/4, with tighter loops. Higher precision producing worse behavior is the opposite of what a quantization-error story predicts — which is a good sign the story was wrong. My unproven hunch is that the flip silently changed which attention kernel gets used rather than merely raising precision, since quantized KV generally requires flash attention while f16 can take a different path. Reverted, theory dead, lesson kept.
Crossing the line and knowing you crossed it are two different measurements.
Where the Premises Are Probably Flawed
Let me do this to myself before someone else does.
There is no frontier baseline here, and that’s the biggest hole in the whole thing. This test compares two machines running the same open-weight model. It says exactly nothing about whether that model is good enough to displace a frontier cloud model on real work. Both boxes scored a median 0.84 against my own 32-case suite — but “these two hosts are equally good” and “this is good enough to bet real work on” are entirely different claims, and I’ve only tested the first one. The second is the question that actually matters, and it’s next on my list. Don’t let me, or anyone, wave this post at it.
My harness could only observe one of the two ways a run stalls — though I think they’re mostly the same thing. Trials ran non-interactively with approvals off, because an unattended benchmark cannot answer prompts. So every failure I measured is the spins until the clock runs out kind, never the stops and asks you something kind. As argued in Finding Three, I believe a spin is largely a request for help with nowhere to go, which is what makes the timeout rate usable as a proxy for “needed a human.”
But it is a rough proxy and I don’t want to oversell it. It cannot separate a run that wanted one clarifying answer from a run that was simply broken, and I have no way to know whether an interactive agent would have asked sooner, later, or about something else entirely. Read 59% as an estimate of how often a session needs you, not a measurement of it.
One model, one task. Everything above is qwen3-coder-next building one small Go CLI. I have no idea yet whether these results are a property of the machines or a property of this specific model on this specific shape of work. A second arm with a smaller model is planned for exactly that reason.
No seed control. A seed is the starting number for the random draw the model makes when it picks the next token from its candidates. Fix the seed and the same prompt yields the identical output every time; leave it unset and every run rolls fresh dice. It’s the difference between an experiment you can re-run and an experiment you can only average. My agent exposes temperature, top-p, top-k and repetition penalty — but no seed. So when a trial does something startling, I cannot re-run that trial to see it again; I can only run another one and hope. The whole comparison rests on per-host aggregates, not on any single run being repeatable.
Uneven n. 19 trials on the GB10, 8 on the ZBook, and 1 on the metric I find most interesting. The quality null result is well-supported. The 6× figure is barely supported at all.
Thermals aren’t instrumented. The ZBook is a 14" laptop. It may well be throttling under three hours of sustained inference. I didn’t measure it. That’s a real hole, and it’s one that would make the laptop look unfairly bad in exactly the long-running scenario where I measured it looking worst.
Ollama isn’t the fast path. I used the same serving stack on both machines because that was the only honest way to hold the variable constant. It’s not necessarily the best stack for either one.
One guy, one harness, one week. See earlier: five bugs found in my own rig. Assume six.
The Anecdotes
Now the unscientific part, which per Bezos might be the trustworthy part.
I have been living with both of these machines. And the lived experience is exactly what the numbers say: on the ZBook, an agentic session feels like it’s grinding. Not slow in a “this token is taking a while” sense — slow in a “why are you running that same command again” sense. On the GX10, sessions feel like they converge. I reach for the desk box without thinking about it now, and I noticed that habit forming well before I had a single number to justify it.
That’s what makes me willing to stand behind the shape of these findings while cheerfully admitting the specific multipliers are soft. The instrument and the hands agree. When they disagree, I’ll go debug the instrument.
What I Take Away
With the caveat, stated plainly above, that the frontier-comparison question is still wide open and it’s the one that ultimately decides anything.
Local inference for agentic coding is real enough to plan around, and the appliance is the right shape. A shared, mains-powered box that does one job is the unit that makes sense. Not an inference server per person — you’d pay laptop prices for a fraction of the throughput and spend the difference on wasted turns.
Don’t buy the laptop for this. Buy it because it’s a superb development machine that happens to be able to do this in a pinch, on a plane, with no network. That’s a genuinely valuable fallback. It is not a capacity plan.
Wasted turns are a cost line, not a latency annoyance. This is the one I’ll keep repeating. Point agentic work at a metered endpoint and you’re exposed to a failure mode where the bill scales with the model’s confusion — and nothing tells you until the invoice arrives. That needs a meter and a cap on it, which is exactly the metering exercise I argued for in May. Except now I’ve watched an agent run up an 18× tab right in front of me.
And I need better alerting — that one’s on me, not the hardware. The entire premise of unattended agentic work is that you leave. Which means the instant a run needs a human — a question, a hard failure, a loop it can’t claw out of — something ought to come find me, instead of waiting politely in a terminal I stopped looking at forty minutes ago. I don’t have that today, and running this benchmark made it embarrassingly obvious that I should: I lost real hours to sessions that had been parked long before I wandered back. No amount of tokens per second fixes that.
The encouraging part is that the signal is dead simple. A stuck agent repeats itself — in my failed runs the last six tool calls reduce to one distinct command. You don’t need a model to notice that. You need a few lines of string comparison and something that can fire a push notification. And my agent does ship a loop guard: it fired exactly once against 1222 tool calls, and it never once caught a two-command A-B-A-B cycle. So the detector exists and is nowhere near aggressive enough.
Spotting the spin is easy. Nobody has bothered to make it shout. That’s a notification problem, not an inference problem, and it’s going on my build list.
And the honest one: this does not get you out of the cloud. For hard reasoning, long context, and the work that actually matters, the frontier models are still the frontier models. What local buys you is the long tail — and per the NRE argument, moving the long tail off the meter is where the compounding savings live. “Local where possible, cloud for the heavy lifting” is still where I think this lands. I just have more evidence for it than I did in May, and one number — 1567 — that makes the case better than anything I could have written.
Conclusion: My Favorite Notebook PC, Ever
Let me be completely clear about something, because the numbers above could easily read as a hit piece and they are not.
The HP ZBook Ultra G1a is my favorite notebook PC ever. Ever. Not “of the last few years.” Ever. It is a 14-inch machine that weighs nothing, goes in a backpack without a thought, and holds 128 GB of unified memory. As a workhorse development machine it is astonishing — it compiles, it runs containers, it drives my whole workflow, and it does it in a chassis I forget I’m carrying. I have owned a lot of laptops. This is the one. It’s a company machine and I’d buy one with my own money tomorrow, which is about the highest compliment I know how to pay a piece of hardware.
It is not perfect and I won’t pretend otherwise. The built-in camera does not work. At all. The AMD ISP4 camera driver stack isn’t upstream yet, and worse, loading it wedges an I²C controller and takes the trackpad down with it — which I spent an afternoon chasing to ground and wrote up here. My fix is to blacklist the whole camera stack, which is lossless only because the camera was never working anyway. I use an external webcam. That’s the honest state of it: bleeding-edge silicon, incomplete Linux enablement, and a workaround that costs me a feature I never got to have.
But here’s the thing I actually set out to learn, and I got a clean answer: as an inference server, it does not live up to my hopes. I wanted the ZBook to be the whole stack — agent and model, in one bag, on a plane, no network. It can technically do that. It produces code just as good as the appliance does. It’s just going to make me wait, and worse, it’s going to spend a lot of that wait re-running commands it already ran.
So the division of labor in my shop is now settled, and it isn’t the one I wanted:
- The GX10 serves the model. It’s a mains-powered appliance that sits there and does one job well.
- The ZBook does everything else, and it’s the best machine I’ve ever done “everything else” on.
That’s a good outcome, and a cheaper one than I expected. It’s just not the outcome I was rooting for — and I think being honest about which of those two things is which is most of what makes a test like this worth running at all.
Next up: a second model arm to find out whether any of this is about the machines or just about this one model. Then the comparison that actually matters — this open-weight model against a frontier model on the same frozen task, so I can finally say something defensible about good enough rather than just equally good. And more ZBook trials, because n=1 is not a number, it’s an anecdote wearing a lab coat.
If you’ve run something similar on Strix Halo — especially if you’ve got ROCm tuned better than I do, or you’ve instrumented thermals — I would genuinely love to be told I measured this wrong. Drop me a note on LinkedIn.