<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Laurentius Judhianto</title>
    <description>The latest articles on DEV Community by Laurentius Judhianto (@laurnts).</description>
    <link>https://dev.to/laurnts</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3962808%2F0fc6e741-fc75-49d7-96b3-c32ba7a72e27.jpg</url>
      <title>DEV Community: Laurentius Judhianto</title>
      <link>https://dev.to/laurnts</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/laurnts"/>
    <language>en</language>
    <item>
      <title>How I Made a Luma Theme Faster Than Hyva on Hypernode — Without Spending Days</title>
      <dc:creator>Laurentius Judhianto</dc:creator>
      <pubDate>Wed, 10 Jun 2026 14:33:47 +0000</pubDate>
      <link>https://dev.to/laurnts/how-i-made-a-luma-theme-faster-than-hyva-on-hypernode-without-spending-days-2b5l</link>
      <guid>https://dev.to/laurnts/how-i-made-a-luma-theme-faster-than-hyva-on-hypernode-without-spending-days-2b5l</guid>
      <description>&lt;h1&gt;
  
  
  How I Made a Luma Theme Faster Than Hyva on Hypernode — Without Spending Days
&lt;/h1&gt;

&lt;p&gt;Hyva on Hypernode is the premium combo for a fast Magento store. But what if your existing Luma theme could beat it — without a rewrite or days of work?&lt;/p&gt;

&lt;p&gt;On paper it shouldn’t have been close. In one corner, Hyva on Hypernode — the premium combo everyone reaches for when a Magento store has to be fast. In the other, a five-year-old Luma theme with a dated design and images not even saved as WebP, running on a plain &lt;a href="https://hetzner.cloud/?ref=AnFggx6ANhCm" rel="noopener noreferrer"&gt;Hetzner&lt;/a&gt; box at roughly half the monthly cost. The old store answered faster.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A disclaimer before anything: this isn’t a knock on Hyva or Hypernode or the agency — all are genuinely excellent, and I’ll show you exactly where they win. I also don’t have access to the Hyva-on-Hypernode box, so I can’t run hardcore server-side metrics on it. This is Lighthouse plus an honest, perceived-speed comparison on two real, live stores — read it as “here’s what I saw,” not a lab verdict.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Credit where it’s due. &lt;a href="https://www.hyva.io/" rel="noopener noreferrer"&gt;Hyva&lt;/a&gt; is the most solid choice in open-source Magento 2 if you want real performance and a nice templating frontend — and the clever part is what it leaves out.&lt;/p&gt;

&lt;p&gt;It pairs Tailwind with Alpine.js (I first met Alpine over in the Laravel world) and sheds the pile of old library bloat Magento carried for years. Tailwind especially: you build a frontend without the CSS quietly ballooning.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Small personal aside. I’ve believed in this approach for a long time. Around 10 years ago, while I was still an employee, my habit of leaning on utility classes right in the markup earned me some side-eye — this was the Bootstrap-4-hung-the-moon era, before Tailwind existed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now utility-first is the industry standard, all AI generated is all Tailwind. Sigh.... I guess I was just early.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hyva is also a relief after the PWA detour. Magento 2’s frontend is hard enough on its own; PWA Studio made it dramatically harder — a completely separate stack with its own build and deploy procedure, foreign to anyone (inc. me) whose muscle memory is PHP. A lot of teams bounced off it. Hyva went the other way: modern interactivity without abandoning the .phtml and XML we already knew, and that’s a big part of why it won.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Split frontend and backend might still have its comeback — as AI-agent aces Javascript like Magnus Carlsen plays blindfolded Chess against 8 Grand masters, and something like Claude can design and build a frontend end to end in seconds, a decoupled stack could finally be worth the overhead. But that’s a story for another day.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Anyway — enough about Hyva. We all know it’s &lt;del&gt;good&lt;/del&gt; great. So why wouldn’t a merchant just go straight for it? Cost, mostly — and not mine, theirs. A Hyva license (recently made free, hooray) plus a premium modules from Amasty and host like Hypernode is a real monthly bill, and plenty of merchants simply don’t want to take it on.&lt;/p&gt;

&lt;p&gt;And it isn’t only hosting and licensing: moving to Hyva means every module you depend on has to be adapted to its frontend — Hyva-compatible builds or porting work — more cost and more time before you’ve sold a single extra product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting the ground
&lt;/h2&gt;

&lt;p&gt;So I set up an honest comparison, and laid out the rules first.&lt;/p&gt;

&lt;p&gt;The deal: a comparable Hypernode plan runs €637/month. The StoreFrame side is €340 — €250 for the management hub plus €90 for the Hetzner bare metal. Here's the hardware, side by side:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;StoreFrame (Luma Based)&lt;/th&gt;
&lt;th&gt;Hypernode (Hyva)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hetzner EX101 — bare metal&lt;/td&gt;
&lt;td&gt;Jackal S — dedicated tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CPU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Intel i9-13900 · 24 cores / 32 threads · up to 5.6 GHz&lt;/td&gt;
&lt;td&gt;AMD Ryzen · 12 cores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;64 GB DDR5 ECC · 4400 MT/s&lt;/td&gt;
&lt;td&gt;64 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2× 1.92 TB Gen4 NVMe&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost / month&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;€340/mo (€250 hub + €90 server)&lt;/td&gt;
&lt;td&gt;€637/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The StoreFrame stack: OpenResty with Brotli, HTTP/3 and QUIC, three Redis instances, MariaDB, PHP-FPM, OpenSearch, our licensed Luma-based theme (which include &lt;a href="https://swissuplabs.com/page-speed.html" rel="noopener noreferrer"&gt;Swissup module for page speed&lt;/a&gt;), and Varnish, obviously. There’s no magic sauce — just properly tuned Ubuntu and Docker containers working in sync.&lt;/p&gt;

&lt;p&gt;And the honest handicaps, all on my side: the Luma store runs an older Magento 2.4.8 on PHP 8.4 — a basic theme - plain StoreFrame theme design I've made 5 years ago (back then the focus was not the design, just to get a proper single Magento2 webshop merge from multiple Magento1), so the design itself is dated. The images aren’t even optimized to WebP. The Hyva-on-Hypernode store is newer across the board, fresh - clean and sharp.&lt;/p&gt;

&lt;h2&gt;
  
  
  A level playing field
&lt;/h2&gt;

&lt;p&gt;One rule mattered more than the rest: keep it a level playing field. I deliberately left the exotic performance options on the shelf — no FrankenPHP, no ARM, none of the tricks StoreFrame can pull.&lt;/p&gt;

&lt;p&gt;Just a familiar, almost boring stack on plain x86 that any Magento team would recognise. The point wasn’t to win with something you’ve never heard of; it was to show how a setup everyone can relate to actually holds up. If it works on the boring stack, it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually saw
&lt;/h2&gt;

&lt;p&gt;You can scan them yourself:&lt;br&gt;
&lt;a href="https://fastartechniek.storeframe.store" rel="noopener noreferrer"&gt;fastartechniek.storeframe.store&lt;/a&gt; (Hetzner bare metal + StoreFrame Luma)&lt;br&gt;
&lt;a href="https://fastarshop.nl" rel="noopener noreferrer"&gt;fastarshop.nl&lt;/a&gt; (Hyva + Hypernode)&lt;/p&gt;

&lt;p&gt;At a glance, the Luma store doesn’t feel slow at all — it’s genuinely comparable. Try Add to Cart and filter on layered navigation, feels a snap on both.&lt;/p&gt;

&lt;p&gt;On uncached pages, and especially in the backend, it’s actually a tad quicker.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The fastartechniek.storeframe.store demo stays online only through the end of June 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favxdmhtz6mosdjawo3if.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favxdmhtz6mosdjawo3if.png" alt="StoreFrame Base Theme" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3m8v7hrnhxrcs1p68ktx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3m8v7hrnhxrcs1p68ktx.png" alt="Hyva Magento Theme" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which sounds strange until you remember what’s underneath: raw bare-metal performance versus a managed hosting platform.&lt;/p&gt;

&lt;p&gt;So the split is honest — we win on raw performance; Hypernode wins on stability, and Hyva wins on Lighthouse.&lt;/p&gt;

&lt;p&gt;Here are the hard figures — three identical pages on each store (the homepage, a category, and the exact same product), five runs each:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server response time (TTFB) — the bare-metal win&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;StoreFrame (Luma Based)&lt;/th&gt;
&lt;th&gt;Hyva&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Homepage&lt;/td&gt;
&lt;td&gt;16ms&lt;/td&gt;
&lt;td&gt;38ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Category page&lt;/td&gt;
&lt;td&gt;21ms&lt;/td&gt;
&lt;td&gt;106ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product page&lt;/td&gt;
&lt;td&gt;18ms&lt;/td&gt;
&lt;td&gt;49ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Google Lighthouse — mobile&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;StoreFrame (Luma Based)&lt;/th&gt;
&lt;th&gt;Hyva&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Homepage&lt;/td&gt;
&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;66&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Category page&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;td&gt;47&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product page&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;td&gt;90&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Google Lighthouse — desktop&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;StoreFrame (Luma Based)&lt;/th&gt;
&lt;th&gt;Hyva&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Homepage&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Category page&lt;/td&gt;
&lt;td&gt;77&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product page&lt;/td&gt;
&lt;td&gt;74&lt;/td&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Measured early on a Sunday morning, around 5-6 AM CET — on purpose: that's when this B2B shop sees almost no real traffic, so neither store is fighting load. Google PageSpeed Insights (Lighthouse 13.3.0), median of 5 runs, across three identical pages — the homepage, a category, and the exact same product on both stores.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Server response” is PageSpeed Insight's server-response-time. The Luma side runs lean and stock — no WebP, no CDN, no critical-CSS, no JS deferral — to keep it a level playing field; the Hypernode store is proxied through Cloudflare, so this is origin to origin. Lighthouse scores still swing ±10–15 run-to-run on these heavy pages.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcdocpxy67kgsbchepmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcdocpxy67kgsbchepmh.png" alt="Fastarshop Legacy Luma" width="800" height="665"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6c326mphtfonbd9gyim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6c326mphtfonbd9gyim.png" alt="Fastarshop New Hyva" width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Legacy site — the tuned Luma theme on StoreFrame bare metal (fastartechniek.storeframe.store). The table below is its 10 runs:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://fastartechniek.storeframe.store/"&lt;/span&gt;   &lt;span class="c"&gt;# legacy: Luma theme, StoreFrame on bare metal&lt;/span&gt;
&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%-4s %-13s %-11s %-13s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; run &lt;span class="s2"&gt;"appconn(ms)"&lt;/span&gt; &lt;span class="s2"&gt;"ttfb(ms)"&lt;/span&gt; &lt;span class="s2"&gt;"srv-wait(ms)"&lt;/span&gt;
&lt;span class="nb"&gt;wait&lt;/span&gt;&lt;span class="o"&gt;=()&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 &lt;span class="nv"&gt;$N&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;app ttfb &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{time_appconnect} %{time_starttransfer}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nv"&gt;sw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN{printf &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;%.1f&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, (&lt;/span&gt;&lt;span class="nv"&gt;$ttfb&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="s2"&gt;)*1000}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%-4s %-13s %-11s %-13s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN{printf &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;%.1f&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="s2"&gt;*1000}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN{printf &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;%.1f&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$ttfb&lt;/span&gt;&lt;span class="s2"&gt;*1000}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$sw&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;wait&lt;/span&gt;+&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$sw&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;done
&lt;/span&gt;&lt;span class="nv"&gt;median&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{v[NR]=$1} END{print (NR%2)?v[int(NR/2)+1]:(v[NR/2]+v[NR/2+1])/2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"----------------------------------------------"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"median server-wait over &lt;/span&gt;&lt;span class="nv"&gt;$N&lt;/span&gt;&lt;span class="s2"&gt; runs: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;median&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ms"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;run  appconn&lt;span class="o"&gt;(&lt;/span&gt;ms&lt;span class="o"&gt;)&lt;/span&gt;   ttfb&lt;span class="o"&gt;(&lt;/span&gt;ms&lt;span class="o"&gt;)&lt;/span&gt;    srv-wait&lt;span class="o"&gt;(&lt;/span&gt;ms&lt;span class="o"&gt;)&lt;/span&gt;
1    73.5          88.0        14.5
2    107.1         112.9       5.8
3    88.9          100.5       11.6
4    83.9          90.2        6.3
5    54.6          60.8        6.1
6    88.8          100.2       11.4
7    64.0          74.5        10.5
8    70.5          82.8        12.3
9    64.8          75.7        11.0
10   58.3          68.5        10.2
&lt;span class="nt"&gt;----------------------------------------------&lt;/span&gt;
median server-wait over 10 runs: 10.75 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Current production — the live Hyva store on Hypernode, behind Cloudflare (&lt;a href="http://www.fastarshop.nl" rel="noopener noreferrer"&gt;www.fastarshop.nl&lt;/a&gt;). The table below is its 10 runs:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://www.fastarshop.nl/"&lt;/span&gt;   &lt;span class="c"&gt;# current production: Hyva on Hypernode (Cloudflare)&lt;/span&gt;
&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%-4s %-13s %-11s %-13s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; run &lt;span class="s2"&gt;"appconn(ms)"&lt;/span&gt; &lt;span class="s2"&gt;"ttfb(ms)"&lt;/span&gt; &lt;span class="s2"&gt;"srv-wait(ms)"&lt;/span&gt;
&lt;span class="nb"&gt;wait&lt;/span&gt;&lt;span class="o"&gt;=()&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 &lt;span class="nv"&gt;$N&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;app ttfb &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{time_appconnect} %{time_starttransfer}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nv"&gt;sw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN{printf &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;%.1f&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, (&lt;/span&gt;&lt;span class="nv"&gt;$ttfb&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="s2"&gt;)*1000}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"%-4s %-13s %-11s %-13s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN{printf &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;%.1f&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="s2"&gt;*1000}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s2"&gt;"BEGIN{printf &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;%.1f&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$ttfb&lt;/span&gt;&lt;span class="s2"&gt;*1000}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$sw&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;wait&lt;/span&gt;+&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$sw&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;done
&lt;/span&gt;&lt;span class="nv"&gt;median&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{v[NR]=$1} END{print (NR%2)?v[int(NR/2)+1]:(v[NR/2]+v[NR/2+1])/2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"----------------------------------------------"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"median server-wait over &lt;/span&gt;&lt;span class="nv"&gt;$N&lt;/span&gt;&lt;span class="s2"&gt; runs: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;median&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ms"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;run  appconn&lt;span class="o"&gt;(&lt;/span&gt;ms&lt;span class="o"&gt;)&lt;/span&gt;   ttfb&lt;span class="o"&gt;(&lt;/span&gt;ms&lt;span class="o"&gt;)&lt;/span&gt;    srv-wait&lt;span class="o"&gt;(&lt;/span&gt;ms&lt;span class="o"&gt;)&lt;/span&gt;
1    101.2         217.0       115.8
2    60.6          183.3       122.7
3    55.6          205.4       149.7
4    54.2          198.5       144.3
5    48.9          166.8       117.9
6    50.7          165.5       114.9
7    57.5          215.9       158.3
8    52.8          178.4       125.6
9    51.7          135.1       83.4
10   67.4          175.9       108.5
&lt;span class="nt"&gt;----------------------------------------------&lt;/span&gt;
median server-wait over 10 runs: 120.3 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;A note on method: both snippets run from a single fixed host, so these are origin-side server-response times — not Google’s PageSpeed vantage. The legacy store is hit directly; the production store is Cloudflare-fronted (served dynamically, proxied to the Hypernode origin), so its figure includes that extra network hop and isn’t pure origin think-time. What’s comparable here is the run-to-run median and the size of the gap, not the raw milliseconds.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So who wins?
&lt;/h2&gt;

&lt;p&gt;The honest answer splits along what you choose to measure. By TTFB — the time the server takes to answer at all — yes, we win, and not by a hair: uncached pages come back genuinely quick, and the cached ones land right alongside Hyva, near enough to call even.&lt;/p&gt;

&lt;p&gt;All of that with nothing fancy under the hood — just a plain, properly tuned stack. But if the number you live by is the Lighthouse score, Hyva still takes it here. Both are true at once; pick the benchmark that matches what your store actually needs.&lt;/p&gt;

&lt;p&gt;So did I actually win? On the one metric I set out to beat — raw server response — yes. Under the conditions I laid out (idle, cached, same page), a tuned Luma store on Hetzner bare metal answers faster than Hyva on Hypernode. And to be clear about the matchup: this is a Jackal S box (also Hypernode dedicated).&lt;/p&gt;

&lt;p&gt;Most Hypernode shops I've seen run Falcon — their common tier — and Hypernode scales well past this into far heavier, far pricier configurations that "might pull ahead again", yet I doubt as OpenStack is another layer of virtualization. I'm not racing those. The point was never “I beat a great platform” — it's that fast doesn't have to be expensive.&lt;/p&gt;

&lt;p&gt;If you have the budget, Hyva on Hypernode — and I mean that. It wins on Lighthouse, on the things Google rewards, on look-and-feel and the overall experience, and it’s built on newer technology that earns its price. (And if you genuinely want to go nuts on speed, Hyva on bare metal would be the ridiculous best of both — a post for another day.)&lt;/p&gt;

&lt;p&gt;Two honest caveats. On SEO: yes, Hyva's stronger Lighthouse scores feed Google's ranking signals — though how much weight Core Web Vitals really carry today is anyone's guess; nobody seems sure anymore.&lt;/p&gt;

&lt;p&gt;And on what I didn't measure: this was page-load speed, not load capacity — requests per second, behaviour under concurrency, tail latency at peak weren't tested here.&lt;/p&gt;

&lt;p&gt;That said, the StoreFrame box runs more CPU cores (24 vs 12) at the same 64 GB RAM on dedicated bare metal — so on paper it has more headroom and should hold up at least as well under pressure. Theoretically. That's a benchmark for another day.&lt;/p&gt;

&lt;p&gt;And you don’t even need bare metal to get here. Bare metal is the extreme — Fastarshop is a high-traffic store (more than 5 multi-sites), so it earns it. For most merchants, without that kind of traffic, a normal Hetzner cloud box with 64 GB of RAM is plenty: not quite as fast as raw bare metal, but comfortably fast enough. Same tuned stack, smaller bill.&lt;/p&gt;

&lt;p&gt;And that’s only the comparison against the premium end. Plenty of Magento 2 stores still run on shared hosting — cPanel and the like — oversubscribed and creaking, sharing a box with who-knows-what, especially with the daily dose of ZeroDay we face today. Against that, a properly tuned cloud server isn’t a close call; it’s night and day. If that’s where you are, the jump is bigger than anything in this post.&lt;/p&gt;

&lt;p&gt;So who is &lt;a href="https://dev.to/blog/hypernode-great-hosting-why-i-built-storeframe"&gt;StoreFrame&lt;/a&gt; for? Merchants who’d rather keep their Luma store — whether that’s about cost or any other reason — but still want a faster, modern-performing alternative. Let the server do the work. If that’s you, that’s exactly where we can help.&lt;/p&gt;

&lt;p&gt;One last thing. How does a plain server — root access, port 22, and nothing else — turn into any of this? That took me five years, and honestly it’s a story I haven’t seen told anywhere. I’ll give it &lt;a href="https://dev.to/blog/magento-2-performance-optimization-guide-2026"&gt;its own post&lt;/a&gt;. Trust me on that one — stay tuned.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rather keep your store and just make it faster? StoreFrame runs your existing Magento fully tuned on your own cloud — no re-platforming, no theme swap, operated by AI plus a human.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.storeframe.io" rel="noopener noreferrer"&gt;See how StoreFrame works&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>performance</category>
      <category>devops</category>
      <category>webdev</category>
      <category>saas</category>
    </item>
    <item>
      <title>Hypernode Is Great at Magento Hosting. Why I Built StoreFrame Anyway.</title>
      <dc:creator>Laurentius Judhianto</dc:creator>
      <pubDate>Tue, 02 Jun 2026 09:40:01 +0000</pubDate>
      <link>https://dev.to/laurnts/hypernode-is-great-at-magento-hosting-why-i-built-storeframe-anyway-4hmj</link>
      <guid>https://dev.to/laurnts/hypernode-is-great-at-magento-hosting-why-i-built-storeframe-anyway-4hmj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fucc92umognfujk1594da.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fucc92umognfujk1594da.webp" alt="StoreFrame Connected Hub" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hypernode is genuinely great at Magento hosting. So why did I build StoreFrame anyway? The answer was never about where a store runs.
&lt;/h2&gt;

&lt;p&gt;I started where a lot of Magento people start: the frontend. I built themes, and for years that was the whole job. I was happy there — until I tried to grow past it and a Magento upgrade bit me, hard. (Hyva makes the theme layer a much nicer place to live now. I’ll come back to that.) The lesson stuck: if I wanted to keep clients fast and take on more of them without cloning myself, I had to look past the theme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest confession:&lt;/strong&gt; I’m not a backend developer. I still couldn’t tell you with a straight face what a private versus a public method really changes. So renting hosting — letting people who actually understand servers run the servers — was the only sensible call. Hypernode especially: secure, reliable, properly tuned for Magento. (Somewhere in the back of my head was a smaller, cheekier thought too: if I could ever match that for less, I’d pocket the difference. A solo dev is allowed to dream.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then the walls went up&lt;/strong&gt;&lt;br&gt;
I got curious about performance, and everything I reached for was locked.&lt;/p&gt;

&lt;p&gt;A newer PHP version? Not yet. MariaDB instead of MySQL? This hosting doesn’t allow it. Swap Redis for KeyDB? Sure — except no root, so I couldn’t install it. Tengine, Alibaba’s nginx fork? I even tried building it from the makefile myself — nope, slow, and nowhere to run it anyway. The Elasticsearch plugin ElasticSuite needs? Off the table. Nope, and nope again. Every change that might have made a store faster ended at the same wall.&lt;/p&gt;

&lt;p&gt;And it keeps happening. Today everyone’s talking about ARM and FrankenPHP — genuinely exciting for Magento. Where does a curious developer actually go to test them on managed hosting? Nowhere. You read the post and close the tab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One layer at a time&lt;/strong&gt;&lt;br&gt;
So I stopped waiting for permission and started doing it myself — one layer at a time. First, a server I could actually log into as root. Then the stack on top, tuned by hand. Then I wanted to see what was happening — traffic, performance, what was slow and when — so I wired up Grafana and proper monitoring. Then it needed to survive a reboot. Then a second client, then a tenth — each one ideally identical to the last, so I wasn’t relearning every box. Every problem I solved uncovered the next one underneath it.&lt;/p&gt;

&lt;p&gt;And I massively underestimated how hard running your own hosting actually is. There’s a reason managed hosts exist and charge what they do. For a while it felt like I’d traded a cage for a pile of pager duty — more freedom, yes, but every layer now mine to keep alive, alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And then AI arrived&lt;/strong&gt;&lt;br&gt;
And then it all made sense.&lt;/p&gt;

&lt;p&gt;It started by covering the technical ground I don’t have. Building the HUB is genuinely hard, and I’d know: this is my third attempt at it. The first two never matched what I had in my head — this one finally did, across code, design, UX, and sheer completeness. AI closed the gaps I couldn’t close alone, and that on its own is worth a 10x engineer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The StoreFrame HUB dashboard&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhus7xpqkwrzrs5wb457s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhus7xpqkwrzrs5wb457s.png" alt="StoreFrame Unified Control Plane" width="799" height="581"&gt;&lt;/a&gt;&lt;br&gt;
The HUB, third time around — the one that finally matched what I had in my head.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So — did it scale?&lt;/strong&gt;&lt;br&gt;
That was the whole point: going from one solo developer to running more stores without becoming many people. Did it work? Yes. A standardised stack I fully control, plus an AI that closes the gaps I can’t, means I can take on more without drowning in it. Hypernode is still great Magento hosting — I built StoreFrame anyway because I couldn’t stop tinkering, couldn’t scale myself, and AI is what finally turned the whole pile of layers into leverage.&lt;/p&gt;

&lt;p&gt;You can read more here &lt;a href="https://www.storeframe.io/how-were-different" rel="noopener noreferrer"&gt;storeframe vs hypernode&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The one thing I haven’t put to the test here is raw performance — whether a setup like this can actually keep pace with the premium stacks. That’s the &lt;a href="https://www.storeframe.io/blog/luma-faster-than-hyva-on-hypernode" rel="noopener noreferrer"&gt;next post&lt;/a&gt;: a well-tuned Luma theme on Hetzner bare metal against Hypernode with Hyva. Stay tuned.&lt;/p&gt;

</description>
      <category>magento</category>
      <category>ai</category>
      <category>hosting</category>
      <category>claude</category>
    </item>
  </channel>
</rss>
