<?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: Jonas Scholz</title>
    <description>The latest articles on DEV Community by Jonas Scholz (@code42cate).</description>
    <link>https://dev.to/code42cate</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F461127%2F034233c4-ba6e-473c-8a8d-783831764a10.jpeg</url>
      <title>DEV Community: Jonas Scholz</title>
      <link>https://dev.to/code42cate</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/code42cate"/>
    <language>en</language>
    <item>
      <title>How We Built Our Own DNS Server</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Fri, 17 Apr 2026 20:30:49 +0000</pubDate>
      <link>https://dev.to/code42cate/how-we-built-our-own-dns-server-4d3k</link>
      <guid>https://dev.to/code42cate/how-we-built-our-own-dns-server-4d3k</guid>
      <description>&lt;p&gt;We wrote a production DNS server in ~1000 lines of Go, migrated thousands of records off Hetzner DNS, and dropped propagation time from "up to 90 minutes" to a few seconds. It uses the hidden primary pattern, Postgres as the event bus, and AXFR + IXFR to push zones to public secondaries. Here's how and why we did it!&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%2Ftcwt2u128tafbfyy61pw.gif" 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%2Ftcwt2u128tafbfyy61pw.gif" alt="gif" width="504" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Hetzner DNS Stopped Working for Us
&lt;/h2&gt;

&lt;p&gt;Every service on Sliplane gets a managed subdomain like my-app-abc123.sliplane.app. That means an A and AAAA record for every running service, pointing at the server IP where the container lives. Records scale linearly with the platform.&lt;/p&gt;

&lt;p&gt;We started with Hetzner DNS because it was free and we already ran most of our infra there. That worked fine for a while, but after 2 years we hit two walls:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Record limits&lt;/strong&gt;: Hetzner DNS has a hard cap per zone. Originally 500, they bumped it to 10k for us (genuinely appreciate that), but at our growth rate we'd blow through that within weeks. Apparently we're one of their biggest DNS users by record count :D&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed&lt;/strong&gt;: After creating a record via the API, it could take up to 90 minutes before Hetzner's own nameservers actually returned it. For a PaaS where someone just deployed a service and wants to visit the URL, that's a rough experience. Although this wasn't consistently that bad, everytime that happened it directly affected the user experience. It simply looked like our platform was broken (which in that case it was!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not Just Use Another Managed Provider?
&lt;/h2&gt;

&lt;p&gt;Fair question. For most people, a managed DNS provider is the right answer. But once you start shopping around at our "scale" and constraints, things get annoying fast:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Contact sales" pricing.&lt;/strong&gt; A lot of the providers that could comfortably handle our record count sit behind "talk to sales" forms. I hate that. Just tell me what it costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-record or per-query billing.&lt;/strong&gt; The ones that do publish pricing often charge per record or per query. We have no idea how many DNS queries we actually serve, so migrating to an unknown pricing model felt like signing a blank check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EU-only.&lt;/strong&gt; We're based in the EU and wanted to keep DNS there too. That narrows the field a lot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And honestly, it sounded fun.&lt;/strong&gt; I'm a bit of a controlfreak and writing a DNS server is the kind of thing you daydream about. A thousand lines of Go felt worth the freedom. In the end, building the thing took less time than getting a meeting with a managed provider would have 😵‍💫&lt;/p&gt;

&lt;p&gt;So we built it ourselves, which brings us to the pattern that made it surprisingly simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Primary Pattern
&lt;/h2&gt;

&lt;p&gt;The reason why this is all way simpler than I initially thought: our DNS server never answers a single public query.&lt;/p&gt;

&lt;p&gt;In DNS, a zone's primary nameserver holds the authoritative records. Secondaries pull copies using &lt;a href="https://en.wikipedia.org/wiki/DNS_zone_transfer" rel="noopener noreferrer"&gt;AXFR&lt;/a&gt; (basically a full zone dump over TCP) and answer public queries just like the primary would. When the primary changes, it sends a NOTIFY to the secondaries, and they pull a fresh copy.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;hidden primary&lt;/strong&gt; takes this one step further, the primary isn't public at all. It only exists to push zone data to secondaries. The public nameservers, the ones listed at your registrar, are all secondaries.&lt;/p&gt;

&lt;p&gt;This means we can run our DNS server wherever we want, use any secondary provider that supports &lt;a href="https://en.wikipedia.org/wiki/DNS_zone_transfer" rel="noopener noreferrer"&gt;AXFR&lt;/a&gt;, and swap providers without changing our server. No lock-in because AXFR and NOTIFY are standard protocols, any compliant secondary will work.&lt;/p&gt;

&lt;p&gt;No anycast, no super redundant ddos protected DNS servers deployed across the globe. Just a few instances of our primary hidden server.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&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%2F1xctjqp3au78ral1xr2r.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%2F1xctjqp3au78ral1xr2r.png" alt="Architecture diagram" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The setup is pretty minimal:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Postgres is the source of truth.&lt;/strong&gt; We install triggers that call &lt;code&gt;pg_notify('dns_zone_changed', '')&lt;/code&gt; whenever a service is created, updated, or deleted. No message queue, no webhooks. Postgres &lt;em&gt;is&lt;/em&gt; the event bus.&lt;/p&gt;

&lt;p&gt;Why not Redis, NATS, or a proper queue? Two reasons. We already run Postgres as our primary database, so &lt;code&gt;LISTEN&lt;/code&gt;/&lt;code&gt;NOTIFY&lt;/code&gt; is "free" (no free lunch, but as free as it gets) infrastructure, nothing new to operate, monitor, or pay for. And the volume is tiny. Zone changes happen a few times per minute at peak, which is laughably low for anything queue-shaped. Reaching for Kafka here would be like renting a shipping container to mail a postcard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sliplane-dns&lt;/strong&gt; is a small Go server (~1000 lines, built on &lt;a href="https://codeberg.org/miekg/dns" rel="noopener noreferrer"&gt;miekg/dns&lt;/a&gt;) that subscribes via &lt;code&gt;LISTEN&lt;/code&gt;, queries Postgres for all managed domains and their IPs, builds the DNS zone, and serves it via AXFR.&lt;/p&gt;

&lt;p&gt;To avoid unnecessary work, we hash all records. If the hash matches the previous zone, nothing happens, no serial bump, no NOTIFY. When the zone actually changes, we bump the SOA serial and send DNS NOTIFY to Hetzner's three secondary IPs. They pull the new zone, and records are live.&lt;/p&gt;

&lt;p&gt;To see what a zone transfer actually looks like, here's a minimal DNS server that only speaks AXFR. It serves a hardcoded zone for &lt;code&gt;example.com&lt;/code&gt; with a single A record (&lt;a href="https://github.com/code42cate/dns-axfr-sample" rel="noopener noreferrer"&gt;full code on GitHub&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/netip"&lt;/span&gt;

    &lt;span class="s"&gt;"codeberg.org/miekg/dns"&lt;/span&gt;
    &lt;span class="s"&gt;"codeberg.org/miekg/dns/rdata"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;soa&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOA&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Hdr&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"example.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TTL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClassINET&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;SOA&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rdata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SOA&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Ns&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"ns1.example.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Mbox&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"admin.example.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;records&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RR&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;soa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Hdr&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"app.example.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TTL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClassINET&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;rdata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Addr&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;netip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MustParseAddr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.2.3.4"&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;soa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;mux&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServeMux&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;mux&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unpack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hijack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Envelope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;records&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Envelope&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RR&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rr&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nb"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TransferOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;srv&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;srv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;":5553"&lt;/span&gt;
    &lt;span class="n"&gt;srv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"tcp"&lt;/span&gt;
    &lt;span class="n"&gt;srv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mux&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;srv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it and pull the zone with dig:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig @localhost &lt;span class="nt"&gt;-p&lt;/span&gt; 5553 example.com AXFR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;example.com.        3600    IN    SOA    ns1.example.com. admin.example.com. 1 0 0 0 0
app.example.com.    300     IN    A      1.2.3.4
example.com.        3600    IN    SOA    ns1.example.com. admin.example.com. 1 0 0 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full zone transfer is just SOA, all records, SOA again. This is roughly what Hetzner's secondaries pull from our production server, just with a few thousand more records in between the two SOAs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Saturday Night DNS Surgery
&lt;/h2&gt;

&lt;p&gt;You can't gradually migrate DNS nameservers. The NS records at the registrar point to either the old set or the new set. There's a cutover window, no way around it.&lt;/p&gt;

&lt;p&gt;We had to switch from Hetzner's nameservers (&lt;code&gt;hydrogen.ns.hetzner.com&lt;/code&gt;, &lt;code&gt;oxygen.ns.hetzner.com&lt;/code&gt;, &lt;code&gt;helium.ns.hetzner.de&lt;/code&gt;) to Hetzner Robot's secondary nameservers (&lt;code&gt;ns1.first-ns.de&lt;/code&gt;, &lt;code&gt;robotns2.second-ns.de&lt;/code&gt;, &lt;code&gt;robotns3.second-ns.com&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;During the transition, resolvers with cached old NS records would still ask the old servers and get stale data until TTL expired. Two things made this manageable: the NS delegation TTL was 5 minutes, and only &lt;em&gt;new&lt;/em&gt; services deployed during that window were affected. Existing A/AAAA records were identical on both sets of nameservers.&lt;/p&gt;

&lt;p&gt;We did it on a Saturday night when platform activity was lowest. It went smooth, no users complained!&lt;/p&gt;

&lt;h2&gt;
  
  
  The One Thing That Bit Us: IXFR
&lt;/h2&gt;

&lt;p&gt;I went into this thinking AXFR was enough. It's the protocol every tutorial shows, every example uses, and it's what I built first. Full zone dump, SOA at the start, SOA at the end, done.&lt;/p&gt;

&lt;p&gt;Turns out Hetzner Robot's secondaries don't just do AXFR. When they already have a zone and see a new SOA serial via NOTIFY, they ask for an &lt;em&gt;incremental&lt;/em&gt; zone transfer first (&lt;a href="https://www.ietf.org/archive/id/draft-ah-dnsext-rfc1995bis-ixfr-02.html" rel="noopener noreferrer"&gt;IXFR, RFC 1995&lt;/a&gt;), a diff of only the records that changed since the old serial. If the primary doesn't speak IXFR, a well-behaved secondary falls back to AXFR. Hetzner Robot apparently doesn't fall back cleanly in every case, so zones weren't updating reliably until we implemented IXFR too.&lt;/p&gt;

&lt;p&gt;IXFR isn't hard, you just keep a small history of recent zone versions and, on request, return the delta between the client's serial and the current one. But it's the kind of thing you'd only discover by actually shipping it against a real secondary. Cheers to whoever wrote that RFC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was It Worth It?
&lt;/h2&gt;

&lt;p&gt;So far, 100%. Propagation went from "up to 90 minutes" to however long it takes to do a zone transfer, which for our zone size is practically instant. The zone grows with the platform without hitting any record ceilings, and we also have full observability baked in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Do This?
&lt;/h2&gt;

&lt;p&gt;Probably not. Use Cloudflare DNS, Route 53, or whatever managed DNS your provider offers. They're fast, they work, and you don't have to think about them.&lt;/p&gt;

&lt;p&gt;But if you &lt;em&gt;do&lt;/em&gt; end up hitting the limits of a managed DNS provider, the hidden primary pattern is worth knowing about. Your primary doesn't need to be public, you can use any AXFR-compatible secondary, and you can swap providers without touching your server.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Jonas, Co-Founder &lt;a href="https://sliplane.io?utm_source=we-built-our-own-dns-server" rel="noopener noreferrer"&gt;sliplane.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>docker</category>
      <category>webdev</category>
    </item>
    <item>
      <title>vCPUs are a marketing scam</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Sat, 24 Jan 2026 22:56:53 +0000</pubDate>
      <link>https://dev.to/code42cate/vcpus-are-a-marketing-scam-21kj</link>
      <guid>https://dev.to/code42cate/vcpus-are-a-marketing-scam-21kj</guid>
      <description>&lt;p&gt;You've probably seen "4 vCPU" on a pricing page and wondered what that actually means. Is it 4 CPU cores? 4 threads? Something else entirely?&lt;/p&gt;

&lt;p&gt;The short answer: a vCPU is whatever the hell your cloud provider decides. Sometimes it's &lt;a href="https://fly.io/docs/machines/cpu-performance/" rel="noopener noreferrer"&gt;a share of CPU time&lt;/a&gt;, sometimes it's &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-optimize-cpu.html" rel="noopener noreferrer"&gt;an actual hardware thread&lt;/a&gt;, and sometimes providers offer both - AWS has regular instances with dedicated threads &lt;em&gt;and&lt;/em&gt; &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances.html" rel="noopener noreferrer"&gt;burstable instances&lt;/a&gt; with CPU credits.&lt;/p&gt;

&lt;p&gt;This post focuses on the quota-based model, because that's where the confusing behavior lives. Understanding how it works will save you debugging headaches.&lt;/p&gt;

&lt;p&gt;To be fair, I dont actually think vCPUs are a scam usually. But it made you click, and now I get to explain to you some fun stuff about Linux CFS!&lt;/p&gt;

&lt;p&gt;If you're a visual learner and want to skip the text, try this out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sliplane.io/blog/vcpus-are-a-marketing-scam#see-it-in-action" rel="noopener noreferrer"&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%2Fcov115fa4zqx5i7vmdxj.png" alt="Visualization" width="678" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The interactive component doesnt work on dev.to, click the image to land on my own blog where it works!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why vCPUs Exist
&lt;/h2&gt;

&lt;p&gt;Most web applications don't need constant CPU. Your server processes a request in milliseconds, then sits idle waiting for the next one. Even under load, CPU usage typically looks like spikes rather than a flat line.&lt;/p&gt;

&lt;p&gt;Giving each customer a dedicated physical core would waste most of that capacity. Instead, providers give you a &lt;em&gt;quota&lt;/em&gt; of CPU time: a baseline you can always use, plus a burst allowance for spikes. If your API needs 50ms of CPU three times per second, that's 150ms out of 1000ms - why pay for the other 850ms?&lt;/p&gt;

&lt;p&gt;There's another reason: "1 core" is meaningless as a unit. A 2025 AMD EPYC core and a 2012 Xeon have completely different performance. A time-based quota at least gives you a consistent allocation, even if what you can accomplish in that time still depends on the underlying hardware.&lt;/p&gt;

&lt;p&gt;To use this model well, you need to understand how it works under the hood.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CFS Bandwidth Controller
&lt;/h2&gt;

&lt;p&gt;Linux uses the &lt;a href="https://docs.kernel.org/scheduler/sched-design-CFS.html" rel="noopener noreferrer"&gt;CFS (Completely Fair Scheduler)&lt;/a&gt; bandwidth controller to manage CPU quotas. Three parameters control everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cpu.cfs_quota_us&lt;/strong&gt;: How much CPU time (in microseconds) you get per period&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cpu.cfs_period_us&lt;/strong&gt;: How long each accounting period is (also in microseconds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cpu.cfs_burst_us&lt;/strong&gt;: The maximum accumulated run-time you can bank (in microseconds)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are cgroup v1 names, which I find easier to understand. If you're configuring this yourself, you're probably on &lt;a href="https://docs.kernel.org/admin-guide/cgroup-v2.html" rel="noopener noreferrer"&gt;cgroup v2&lt;/a&gt;, which uses &lt;code&gt;cpu.max&lt;/code&gt; and &lt;code&gt;cpu.max.burst&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;For example, if your quota is 25,000µs (25ms) and your period is 100,000µs (100ms), you can use 25ms of CPU time every 100ms. That's equivalent to 25% of a single CPU's time - and that might be what "1 vCPU" means on a shared instance.&lt;/p&gt;

&lt;p&gt;The math: &lt;code&gt;quota / period = your CPU share&lt;/code&gt;. A quota of 50ms per 100ms period means 50% of a CPU's time. Note that this is aggregate time across all threads in the cgroup, not pinned to a single core.&lt;/p&gt;

&lt;p&gt;The burst parameter allows unused quota to accumulate. If your app only uses 10ms during one period, the remaining 15ms (partially) gets added to a burst balance. When a later request needs more than your baseline quota, it can draw from this balance to exceed the baseline temporarily. Burst is capped between 0 and your quota, and is often disabled by default.&lt;/p&gt;

&lt;p&gt;Once the burst balance hits zero, you're capped at your baseline until it recovers. It only recovers when you're using less than your baseline - which becomes difficult when requests are queuing up.&lt;/p&gt;

&lt;h2&gt;
  
  
  See It In Action
&lt;/h2&gt;

&lt;p&gt;Play with this simulator to build intuition for how quota and period settings affect latency:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sliplane.io/blog/vcpus-are-a-marketing-scam#see-it-in-action" rel="noopener noreferrer"&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%2Fcov115fa4zqx5i7vmdxj.png" alt="Visualization" width="678" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The interactive component doesnt work on dev.to, click the image to land on my own blog where it works!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Try these experiments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch to "Spiky" workload and watch the balance drain to zero, triggering throttling (red dashed line)&lt;/li&gt;
&lt;li&gt;Increase the baseline to 25% - notice how the balance stays healthier and throttling decreases&lt;/li&gt;
&lt;li&gt;With "Bursty" workload and low baseline, see how bursts drain balance but it recovers during idle periods&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Happens When You Exceed Your Quota
&lt;/h2&gt;

&lt;p&gt;Let's say you have a 25ms quota per 100ms period, and a request comes in that needs 30ms of CPU time to process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your process starts running&lt;/li&gt;
&lt;li&gt;After 25ms, the kernel sees you've used your quota&lt;/li&gt;
&lt;li&gt;Your process gets &lt;strong&gt;paused&lt;/strong&gt; until the next period starts&lt;/li&gt;
&lt;li&gt;75ms later, a new period begins and you get 25ms more&lt;/li&gt;
&lt;li&gt;Your process finishes the remaining 5ms&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Total wall-clock time: 105ms for 30ms of actual work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your process wasn't slow - it was waiting. When you exceed your quota, latency doesn't degrade gracefully. It jumps by the length of the remaining period. That sucks, especially for your P99 latency!&lt;/p&gt;

&lt;h2&gt;
  
  
  When This Works Well
&lt;/h2&gt;

&lt;p&gt;The quota model fits most web workloads because they're inherently bursty - short CPU spikes with idle time in between. If your app averages 10% CPU but occasionally spikes to 50%, the burst balance absorbs those spikes while idle periods let it recover.&lt;/p&gt;

&lt;h2&gt;
  
  
  When This Breaks Down
&lt;/h2&gt;

&lt;p&gt;The model falls apart in a few scenarios:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long synchronous operations&lt;/strong&gt;: A request needing 50ms of CPU with a 25ms quota will always get throttled, regardless of burst balance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Latency-sensitive workloads&lt;/strong&gt;: If P99 latency matters, your longest operations need to fit within your quota.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sustained load&lt;/strong&gt;: Once burst balance depletes and requests queue up, each new request starts mid-period with less quota remaining. The backlog compounds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Size for your longest operations, not average CPU&lt;/strong&gt;: If your P99 request needs 40ms of CPU, a 25ms quota will throttle those requests every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Shorter periods reduce worst-case throttling delay, longer periods increase it&lt;/strong&gt;: A 50ms period means you wait at most 50ms when throttled. A 100ms period means potentially waiting 100ms. The tradeoff is how quota gets distributed within each period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Watch for cascade effects&lt;/strong&gt;: When one request gets throttled and takes longer, it holds a connection longer, which can cause queuing, which makes the next request start with less remaining quota in the period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. "Low CPU usage" can be misleading&lt;/strong&gt;: If your monitoring shows 20% CPU but users complain about latency, check throttling stats. You might be at 80% of your &lt;em&gt;quota&lt;/em&gt; while only using 20% of the physical core.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Consider dedicated CPU for latency-critical paths&lt;/strong&gt;: If consistent latency matters more than cost, dedicated CPU instances guarantee you won't share with noisy neighbors. But of course, "dedicated" also has many different definitions. Sometimes that just means a bigger slice!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;vCPUs aren't a scam; they're a mostly sensible way to share compute resources efficiently. The quota system works great for bursty workloads, which is most workloads.&lt;/p&gt;

&lt;p&gt;The key is understanding that exceeding your quota doesn't make things "a little slower" - it makes them &lt;em&gt;wait for the next period&lt;/em&gt;. Once you internalize that, you can make informed decisions about resource sizing and understand why latency sometimes spikes even when CPU "looks fine."&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes &amp;amp; References
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The cover image illustration was generated with AI.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.rst" rel="noopener noreferrer"&gt;Linux kernel CFS bandwidth controller documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fly.io/docs/machines/cpu-performance/" rel="noopener noreferrer"&gt;Fly.io - Understanding VM CPU Performance&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lwn.net/Articles/844976/#t" rel="noopener noreferrer"&gt;LWN: Control Group CPU throttling and bandwidth&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bsky.app/profile/adamlogic.com/post/3lng4xyvbez2g" rel="noopener noreferrer"&gt;Adam Logic on Bluesky - vCPU explanations&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>docker</category>
      <category>webdev</category>
    </item>
    <item>
      <title>free yourself of overpriced docusign and self-host DocuSeal instead 🦭🦭🦭</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Fri, 09 Jan 2026 16:42:18 +0000</pubDate>
      <link>https://dev.to/code42cate/free-yourself-of-overpriced-docusign-and-self-host-docuseal-instead-59jh</link>
      <guid>https://dev.to/code42cate/free-yourself-of-overpriced-docusign-and-self-host-docuseal-instead-59jh</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/atakanozt/self-hosting-docuseal-the-easy-way-1o4m" class="crayons-story__hidden-navigation-link"&gt;Self-hosting DocuSeal the easy way&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/atakanozt" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F3702146%2F3867f18e-5c71-4fd2-a22e-36e9630d0cf5.jpg" alt="atakanozt profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/atakanozt" class="crayons-story__secondary fw-medium m:hidden"&gt;
              atakanozt
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                atakanozt
                
              
              &lt;div id="story-author-preview-content-3161023" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/atakanozt" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F3702146%2F3867f18e-5c71-4fd2-a22e-36e9630d0cf5.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;atakanozt&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/atakanozt/self-hosting-docuseal-the-easy-way-1o4m" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 9&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/atakanozt/self-hosting-docuseal-the-easy-way-1o4m" id="article-link-3161023"&gt;
          Self-hosting DocuSeal the easy way
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/docker"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;docker&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/selfhosted"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;selfhosted&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/atakanozt/self-hosting-docuseal-the-easy-way-1o4m" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;17&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/atakanozt/self-hosting-docuseal-the-easy-way-1o4m#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>docker</category>
      <category>selfhosted</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Tech Stack Lessons from scaling 20x in a year</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Fri, 09 Jan 2026 12:13:03 +0000</pubDate>
      <link>https://dev.to/code42cate/tech-stack-lessons-from-scaling-20x-in-a-year-1ekh</link>
      <guid>https://dev.to/code42cate/tech-stack-lessons-from-scaling-20x-in-a-year-1ekh</guid>
      <description>&lt;p&gt;A year ago, I wrote about &lt;a href="https://dev.to/blog/the-tech-stack-to-build-a-cloud-provider"&gt;our tech stack&lt;/a&gt; and how it helped us run a lean cloud computing startup. Since then, we've scaled over 20x. That kind of growth is fun, but also breaks &lt;em&gt;a lot of&lt;/em&gt; things and assumptions; and forces you to make hard choices, quickly :D&lt;/p&gt;

&lt;p&gt;Here's what changed, what stayed the same, and what we learned along the way.&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%2Fhwxtlxty9fyoxp0s42rg.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%2Fhwxtlxty9fyoxp0s42rg.png" alt="Tech Stack" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Stayed the Same
&lt;/h2&gt;

&lt;p&gt;Some things just work. Our frontend is still &lt;a href="http://nuxt.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Nuxt&lt;/strong&gt;&lt;/a&gt; with &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;Typescript&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Tailwind&lt;/strong&gt;&lt;/a&gt; (&lt;a href="https://x.com/adamwathan/status/2008909129591443925" rel="noopener noreferrer"&gt;RIP&lt;/a&gt;). Our backend is still &lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;&lt;strong&gt;Go&lt;/strong&gt;&lt;/a&gt; with &lt;a href="https://github.com/gin-gonic/gin" rel="noopener noreferrer"&gt;&lt;strong&gt;Go-Gin&lt;/strong&gt;&lt;/a&gt;. We still run on &lt;a href="https://hetzner.cloud/?ref=mZziDsGU2VVp" rel="noopener noreferrer"&gt;&lt;strong&gt;Hetzner&lt;/strong&gt;&lt;/a&gt; bare-metal and use &lt;a href="https://firecracker-microvm.github.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Firecracker&lt;/strong&gt;&lt;/a&gt; for virtualization. &lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Terraform&lt;/strong&gt;&lt;/a&gt; still manages our infrastructure. &lt;a href="https://hub.docker.com/_/redis" rel="noopener noreferrer"&gt;&lt;strong&gt;Redis&lt;/strong&gt;&lt;/a&gt; still handles caching. &lt;a href="https://crisp.chat/en/" rel="noopener noreferrer"&gt;&lt;strong&gt;Crisp&lt;/strong&gt;&lt;/a&gt; still powers customer support. AWS SES still sends our transactional emails.&lt;/p&gt;

&lt;p&gt;If it ain't broke, don't fix it.&lt;/p&gt;

&lt;p&gt;But plenty did break — or became too expensive to keep running the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observability: Axiom → Parseable
&lt;/h2&gt;

&lt;p&gt;This was our biggest operational change. Last year I praised &lt;a href="https://axiom.co/" rel="noopener noreferrer"&gt;&lt;strong&gt;Axiom&lt;/strong&gt;&lt;/a&gt; for logs. It was great, on the base plan. Until we scaled.&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%2Fmcwkllxfuop6d8l8fbp5.gif" 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%2Fmcwkllxfuop6d8l8fbp5.gif" alt="broke" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As our traffic grew, so did our need for better tracing and more detailed logs. Our Axiom bill exploded past €1,000/month and kept climbing. At that point, you have to ask yourself: is this sustainable? Obviously not lol.&lt;/p&gt;

&lt;p&gt;We migrated to &lt;a href="https://parseable.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Parseable&lt;/strong&gt;&lt;/a&gt;, self-hosted on Kubernetes with &lt;a href="https://min.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Minio&lt;/strong&gt;&lt;/a&gt; for S3-compatible storage, all running on bare-metal. The product still feels early, but the team is responsive and ships fixes fast when something breaks. Big shoutout to &lt;a href="https://www.linkedin.com/in/anantvindal/" rel="noopener noreferrer"&gt;Anant&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/debanitr/" rel="noopener noreferrer"&gt;Deba&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Would I recommend it? If you can't trade boatloads of money for time, yes. Self-hosting observability is work, but at our "scale" (we are still tiny), it's worth it. We still use &lt;a href="https://grafana.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Grafana&lt;/strong&gt;&lt;/a&gt; for dashboards and alerts, that hasn't changed (for now, the bill is starting to hurt).&lt;/p&gt;

&lt;h2&gt;
  
  
  Object Storage: Backblaze → IONOS/Hetzner
&lt;/h2&gt;

&lt;p&gt;Last year we used &lt;a href="http://backblaze.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Backblaze&lt;/strong&gt;&lt;/a&gt; for blob storage. It was cheap and reliable. The problem wasn't technical, it was purely political and a question of positioning.&lt;/p&gt;

&lt;p&gt;As we grew, so did the type of customers we attract. Enterprise customers, especially European ones, started pushing back on storing their data with US providers. GDPR compliance, data sovereignty, internal policies; the reasons varied, but the message was clear. No US providers! So our crusade to replace all US providers began with Backblaze.&lt;/p&gt;

&lt;p&gt;We moved to &lt;a href="https://www.ionos.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;IONOS&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://www.hetzner.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Hetzner&lt;/strong&gt;&lt;/a&gt; for object storage. Are they as good as Backblaze? No, not even close. But they're European, they're (barely) good enough, and they satisfy our customers' requirements. Honestly, if you're not required to use them I wouldn't. It feels like we don't really have a choice here.&lt;/p&gt;

&lt;h2&gt;
  
  
  CDN: Cloudflare → Bunny
&lt;/h2&gt;

&lt;p&gt;Same story as storage. &lt;a href="https://www.cloudflare.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Cloudflare&lt;/strong&gt;&lt;/a&gt; is an incredible product with features we'll never use. But customers asked for a European alternative.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bunny.net/" rel="noopener noreferrer"&gt;&lt;strong&gt;Bunny&lt;/strong&gt;&lt;/a&gt; fits the bill. It's not feature-complete like Cloudflare, but it handles our CDN needs perfectly. It's fast, reasonably priced, and European. In that case this wasn't even a real tradeoff, Bunny does exactly what we need. For our super simple setup the migration took less than 2 hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  CI/CD: GitHub Actions → Namespace
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt;&lt;/a&gt; served us well, but it's stagnated. We needed nested virtualization for testing Firecracker stuff. We needed better performance. GitHub wasn't delivering.&lt;/p&gt;

&lt;p&gt;We moved to &lt;a href="https://namespace.so/" rel="noopener noreferrer"&gt;&lt;strong&gt;Namespace&lt;/strong&gt;&lt;/a&gt; for our runners. It's a great product — also European, which is becoming a theme here. The performance improvements alone were worth the switch.&lt;/p&gt;

&lt;p&gt;That said, we'll probably migrate to completely self-hosted runners eventually. The more we scale, the more control we want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Persistence: The Big One
&lt;/h2&gt;

&lt;p&gt;This was our most significant architectural change. Last year, I bragged about running everything in Postgres with Timescale, including hundreds of millions of analytics rows. That worked great until our database hit 2TB.&lt;/p&gt;

&lt;p&gt;At 2TB, Postgres becomes hard to manage. Stupid queries can take down prod, scaling is painful. Database pros are going to laugh about me here, 2TB is probably nothing in the grand scheme of things! I am not a postgres pro, and honestly wasn't planning on becoming one. Additionally, the cost just started to hurt. Especially considering that we want to do another 20x in 2026.&lt;/p&gt;

&lt;p&gt;So we built something simpler: hot data lives in &lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;Postgres&lt;/strong&gt;&lt;/a&gt;, then gets flushed to S3 as &lt;a href="https://en.wikipedia.org/wiki/Apache_Parquet" rel="noopener noreferrer"&gt;Parquet&lt;/a&gt; files. For queries, we use &lt;a href="https://duckdb.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;DuckDB&lt;/strong&gt;&lt;/a&gt; to read directly from S3. &lt;a href="https://duckdb.org/" rel="noopener noreferrer"&gt;DuckDB&lt;/a&gt; is &lt;strong&gt;amazing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The results surprised us. P99 latency actually improved. Why? Most queries are "give me the last 5 minutes of metrics" or "show me the last 500 logs." That's all hot data sitting in Postgres. Historical queries hit S3, and &lt;a href="https://duckdb.org/" rel="noopener noreferrer"&gt;DuckDB&lt;/a&gt; handles Parquet files like a champ. Those are, if not cached, of course slightly slower.&lt;/p&gt;

&lt;p&gt;This architecture saves money, scales better, and plays to our strengths. We understand S3. We don't understand running a 10TB Postgres cluster :D&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern
&lt;/h2&gt;

&lt;p&gt;Looking back at all these changes, there's a clear pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;European everything.&lt;/strong&gt; Customer pressure pushed us toward EU providers. Again, this isn't a technical decision. It's a business reality when you grow beyond startups and indie hackers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Self-host at scale.&lt;/strong&gt; SaaS products are great until your bill crosses a threshold. Then you have to do the math on whether your time is cheaper than their prices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple beats clever.&lt;/strong&gt; We didn't build a fancy distributed database. We flush data to S3 and query it with &lt;a href="https://duckdb.org/" rel="noopener noreferrer"&gt;DuckDB&lt;/a&gt;. It's not sexy, but it works! (Actually I think the simplicity is quite sexy, but not great for resume-driven development)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;We'll probably self-host our CI runners soon. We're evaluating alternatives to AWS SES since, you know, European.&lt;/p&gt;

&lt;p&gt;The stack will keep evolving. That's the nature of building infrastructure at scale. But the core philosophy stays the same: keep it simple, keep it maintainable, and only add complexity when the problem forces you to.&lt;/p&gt;




&lt;p&gt;That's where we're at in 2026. Twenty times bigger, a few hard lessons learned, and a stack that's more European than ever.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Jonas&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>docker</category>
      <category>devops</category>
      <category>startup</category>
    </item>
    <item>
      <title>How to Deploy NiceGUI Apps with Docker on Sliplane</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Sat, 13 Sep 2025 19:02:08 +0000</pubDate>
      <link>https://dev.to/code42cate/how-to-deploy-nicegui-apps-with-docker-on-sliplane-38c8</link>
      <guid>https://dev.to/code42cate/how-to-deploy-nicegui-apps-with-docker-on-sliplane-38c8</guid>
      <description>&lt;p&gt;NiceGUI is a fantastic Python framework for creating web-based user interfaces with ease. If you've built a NiceGUI app and want to deploy it without the complexity of managing servers, you're in the right place. In this tutorial, I'll show you how to containerize and deploy your NiceGUI application on Sliplane.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we start, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A NiceGUI application ready to deploy&lt;/li&gt;
&lt;li&gt;Docker installed on your local machine (for testing)&lt;/li&gt;
&lt;li&gt;A GitHub repository with your NiceGUI code&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://sliplane.io?utm_source=how-to-deploy-nicegui-apps-on-sliplane" rel="noopener noreferrer"&gt;Sliplane&lt;/a&gt; account&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Prepare Your NiceGUI Application
&lt;/h2&gt;

&lt;p&gt;First, let's make sure your NiceGUI app is production-ready. Here's a basic example of a NiceGUI application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;nicegui&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;

&lt;span class="nd"&gt;@ui.page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hello NiceGUI World!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Click me!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Button clicked!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__mp_main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt;
    &lt;span class="n"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;reload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key points for production deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;host='0.0.0.0'&lt;/code&gt; to accept connections from outside the container&lt;/li&gt;
&lt;li&gt;Use any port you prefer (Sliplane auto-detects ports)&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;reload=False&lt;/code&gt; for production stability&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;if __name__&lt;/code&gt; check to prevent issues with container restarts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Create the Dockerfile
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;Dockerfile&lt;/code&gt; in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; zauberzeug/nicegui:latest&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "main.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This Dockerfile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses the latest official NiceGUI base image (check &lt;a href="https://hub.docker.com/r/zauberzeug/nicegui" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt; for specific versions if needed)&lt;/li&gt;
&lt;li&gt;Installs your dependencies from &lt;code&gt;requirements.txt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copies your application code&lt;/li&gt;
&lt;li&gt;Exposes port 8080&lt;/li&gt;
&lt;li&gt;Runs your main application file&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Create Requirements File
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;requirements.txt&lt;/code&gt; file with your dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nicegui
# Add any other dependencies your app needs
# For example:
# pandas
# requests
# matplotlib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Add Docker Ignore File
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;.dockerignore&lt;/code&gt; file to exclude unnecessary files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;__pycache__
*.pyc
*.pyo
*.pyd
.git
.gitignore
README.md
.pytest_cache
.coverage
venv/
env/
.venv/
.env/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Test Locally
&lt;/h2&gt;

&lt;p&gt;Before deploying, test your container locally:&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="c"&gt;# Build the image&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-nicegui-app &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Run the container&lt;/span&gt;
docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 my-nicegui-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit &lt;code&gt;http://localhost:8080&lt;/code&gt; to verify your app works correctly in the container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Deploy on Sliplane
&lt;/h2&gt;

&lt;p&gt;Now for the easy part! Here's how to deploy your NiceGUI app on Sliplane:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sign up&lt;/strong&gt; for &lt;a href="https://sliplane.io?utm_source=how-to-deploy-nicegui-apps-on-sliplane" rel="noopener noreferrer"&gt;Sliplane&lt;/a&gt; (first 2 days free)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Connect your GitHub repository&lt;/strong&gt; by clicking "Create Service" and selecting your repository&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure your service&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service name: &lt;code&gt;my-nicegui-app&lt;/code&gt; (or your preferred name)&lt;/li&gt;
&lt;li&gt;Keep other settings as default (Sliplane auto-detects ports)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Click Deploy&lt;/strong&gt; and wait about 2-3 minutes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access your app&lt;/strong&gt; at &lt;code&gt;https://my-nicegui-app.sliplane.app&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! Your NiceGUI app is now live and accessible worldwide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automatic Updates
&lt;/h2&gt;

&lt;p&gt;Whenever you push changes to your GitHub repository, Sliplane automatically rebuilds and deploys your application. No manual intervention required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Monthly Cost&lt;/th&gt;
&lt;th&gt;Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sliplane Base&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;€9.00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2 vCPU, 2GB RAM, 40GB SSD&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Cloud Run&lt;/td&gt;
&lt;td&gt;~$132&lt;/td&gt;
&lt;td&gt;2 vCPU, 2GB RAM, pay-per-use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heroku Standard-2X&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;2 vCPU, 2GB RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DigitalOcean App&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;2 vCPU, 2GB RAM, dedicated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sliplane offers excellent value with dedicated resources and no cold starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q: Can I run multiple NiceGUI apps on one server?&lt;/strong&gt;&lt;br&gt;
A: Yes! Sliplane allows unlimited containers per server. Deploy multiple NiceGUI apps and they'll share the server resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Does NiceGUI work well in containers?&lt;/strong&gt;&lt;br&gt;
A: Absolutely. NiceGUI was designed with containerization in mind and works perfectly with Docker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How do I handle file uploads?&lt;/strong&gt;&lt;br&gt;
A: Use NiceGUI's built-in upload component and save files to a persistent volume mounted at &lt;code&gt;/data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Can I use external APIs?&lt;/strong&gt;&lt;br&gt;
A: Yes, NiceGUI apps can make HTTP requests to external APIs. Store API keys as environment variables in Sliplane.&lt;/p&gt;

&lt;p&gt;Ready to deploy your NiceGUI application? &lt;a href="https://sliplane.io?utm_source=how-to-deploy-nicegui-apps-on-sliplane" rel="noopener noreferrer"&gt;Sign up for Sliplane&lt;/a&gt; and get your first 2 days free. No credit card required to start!&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Jonas&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>webdev</category>
      <category>python</category>
    </item>
    <item>
      <title>LLMs are the End of Serverless</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Tue, 05 Aug 2025 01:20:04 +0000</pubDate>
      <link>https://dev.to/code42cate/llms-are-the-end-of-serverless-48ea</link>
      <guid>https://dev.to/code42cate/llms-are-the-end-of-serverless-48ea</guid>
      <description>&lt;p&gt;Remember when serverless was going to revolutionize everything? Well, LLMs just delivered the killing blow.&lt;/p&gt;

&lt;p&gt;Here's the thing: In an AI-assisted coding world, proprietary serverless platforms are dead weight. Why? Because LLMs understand Docker like they understand breathing, but they choke on your special snowflake Lambda configuration.&lt;/p&gt;

&lt;p&gt;Let me explain why serverless was already a scam and how LLMs just made it ten times worse.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Original Sin: Serverless Was Always Broken
&lt;/h2&gt;

&lt;p&gt;Before we get to the LLM angle, let's recap why serverless was already a bad idea:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Promise:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No servers to manage!&lt;/li&gt;
&lt;li&gt;Infinite scale!&lt;/li&gt;
&lt;li&gt;Pay only for what you use!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Reality:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;15-minute execution limits&lt;/li&gt;
&lt;li&gt;Cold starts that make your app feel broken&lt;/li&gt;
&lt;li&gt;Surprise $10,000 bills&lt;/li&gt;
&lt;li&gt;Vendor lock-in so tight it hurts&lt;/li&gt;
&lt;li&gt;Debugging that makes you question your career choices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You know what doesn't have these problems? A container.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter LLMs: The Final Nail in the Coffin
&lt;/h2&gt;

&lt;p&gt;Here's where it gets spicy.&lt;/p&gt;

&lt;p&gt;When you're coding with Claude, ChatGPT, or Cursor, what works better?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A:&lt;/strong&gt; "Deploy this to Docker"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-app &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option B:&lt;/strong&gt; "Deploy this to AWS Lambda with API Gateway, configure the execution role, set up the VPC endpoints, create a deployment package with the right runtime, configure the event source mappings..."&lt;/p&gt;

&lt;p&gt;The LLM's response to Option B: &lt;em&gt;confused screaming&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why LLMs Love Docker (And Hate Your Serverless Platform)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Documentation Density
&lt;/h3&gt;

&lt;p&gt;Docker has been around since 2013. That's over a decade of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stack Overflow answers&lt;/li&gt;
&lt;li&gt;GitHub examples&lt;/li&gt;
&lt;li&gt;Blog posts&lt;/li&gt;
&lt;li&gt;Official docs&lt;/li&gt;
&lt;li&gt;YouTube tutorials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Lambda? Sure, there's documentation. But it's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constantly changing&lt;/li&gt;
&lt;li&gt;Platform-specific&lt;/li&gt;
&lt;li&gt;Full of edge cases&lt;/li&gt;
&lt;li&gt;Buried in AWS's labyrinth of services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an LLM trains on the internet, it sees 1000x more Docker examples than CloudFormation YAML nightmares.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Universal Patterns vs. Proprietary Nonsense
&lt;/h3&gt;

&lt;p&gt;Docker is just Linux containers. The patterns are universal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Environment variables work the same everywhere&lt;/li&gt;
&lt;li&gt;Volumes are just mounted directories&lt;/li&gt;
&lt;li&gt;Networking is standard TCP/IP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Serverless? Every platform invents its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event formats&lt;/li&gt;
&lt;li&gt;Configuration syntax&lt;/li&gt;
&lt;li&gt;Deployment procedures&lt;/li&gt;
&lt;li&gt;Debugging tools&lt;/li&gt;
&lt;li&gt;Billing models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LLMs can't keep up with this Tower of Babel.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Local Development = Better LLM Assistance
&lt;/h3&gt;

&lt;p&gt;Watch this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; "Help me debug why my container isn't connecting to Redis"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM:&lt;/strong&gt; "Let's check your docker-compose.yml, ensure the services are on the same network, verify the connection string..."&lt;/p&gt;

&lt;p&gt;vs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; "Help me debug why my Lambda can't connect to ElastiCache"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM:&lt;/strong&gt; "First, check your VPC configuration, then the security groups, subnet associations, NAT gateway, execution role permissions, and... wait, are you using VPC endpoints? What about the Lambda ENI lifecycle? Did you enable DNS resolution in your VPC?"&lt;/p&gt;

&lt;p&gt;&lt;em&gt;head explodes&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%2Fwm9pxjhdoi2xdk9aeuhv.gif" 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%2Fwm9pxjhdoi2xdk9aeuhv.gif" alt="exploding gif" width="360" height="360"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  "But Serverless Scales!"
&lt;/h2&gt;

&lt;p&gt;So does Kubernetes. So does Docker Swarm. So does literally any container orchestrator.&lt;/p&gt;

&lt;p&gt;But here's the thing: with containers + LLMs, you can actually implement that scaling:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; "Add horizontal autoscaling to my Docker Compose setup"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM:&lt;/strong&gt; "Here's a complete docker-compose.yml with scaling configuration, health checks, and load balancing..."&lt;/p&gt;

&lt;p&gt;vs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; "Add autoscaling to my Lambda"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM:&lt;/strong&gt; "First, create an Application Auto Scaling target, then define a scaling policy using CloudWatch metrics, but make sure your concurrent execution limits don't interfere with account limits, and don't forget about reserved concurrency vs provisioned concurrency..."&lt;/p&gt;

&lt;p&gt;Which one are you actually going to implement correctly?&lt;/p&gt;




&lt;h2&gt;
  
  
  Breaking Free: The Container + LLM Combo
&lt;/h2&gt;

&lt;p&gt;Here's your escape plan:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pick boring technology&lt;/strong&gt;: Docker, PostgreSQL, Redis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use standard patterns&lt;/strong&gt;: REST APIs, background workers, cron jobs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy anywhere&lt;/strong&gt;: VPS, Kubernetes, even &lt;a href="https://sliplane.io?utm_source=serverless-got-one-shotted-by-llms" rel="noopener noreferrer"&gt;Sliplane&lt;/a&gt; (yes, shameless plug)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Let LLMs actually help&lt;/strong&gt;: They understand these tools&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your AI assistant becomes a force multiplier instead of a confused intern.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Future Is Boring (And That's Beautiful)
&lt;/h2&gt;

&lt;p&gt;We're entering an era where AI can write most of our code. But it can only write code for platforms it understands.&lt;/p&gt;

&lt;p&gt;Docker is boring. PostgreSQL is boring. Redis is boring.&lt;/p&gt;

&lt;p&gt;You know what? Boring means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documented&lt;/li&gt;
&lt;li&gt;Predictable&lt;/li&gt;
&lt;li&gt;LLM-friendly&lt;/li&gt;
&lt;li&gt;Actually works&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Serverless is "exciting": excitingly broken, excitingly expensive, excitingly impossible to debug.&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Serverless was already a questionable choice. Now that we code with LLMs, it's practically sabotage.&lt;/p&gt;

&lt;p&gt;Your AI assistant can spin up a complete containerized application in seconds. But ask it to debug your Lambda cold start issues? Good luck.&lt;/p&gt;

&lt;p&gt;The writing's on the wall: In an LLM-powered development world, proprietary platforms are dead weight. Stick to technologies with deep documentation, wide adoption, and standard patterns.&lt;/p&gt;

&lt;p&gt;Or keep fighting with CloudFormation while your competitors ship features. Your choice.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Jonas, Co-Founder of &lt;a href="https://sliplane.io?utm_source=serverless-got-one-shotted-by-llms" rel="noopener noreferrer"&gt;sliplane.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>docker</category>
      <category>startup</category>
    </item>
    <item>
      <title>How to Build Custom Open WebUI Themes</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Mon, 28 Jul 2025 19:41:08 +0000</pubDate>
      <link>https://dev.to/code42cate/how-to-build-custom-open-webui-themes-55hh</link>
      <guid>https://dev.to/code42cate/how-to-build-custom-open-webui-themes-55hh</guid>
      <description>&lt;p&gt;While Open WebUI doesn't have built-in theming support, you can easily customize its appearance by injecting a custom CSS file into the Docker image. This guide will show you how to create your own themed version of Open WebUI.&lt;/p&gt;

&lt;p&gt;Want to see a complete example? Check out our &lt;a href="https://github.com/sliplane/open-webui-theme" rel="noopener noreferrer"&gt;Open WebUI Theme repository on GitHub&lt;/a&gt; for a full working implementation.&lt;/p&gt;

&lt;p&gt;Look at this beautiful (questionable) pink theme:&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%2Fgiy9hw9tkvu0cqwl41y9.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%2Fgiy9hw9tkvu0cqwl41y9.png" alt="custom" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker installed on your system&lt;/li&gt;
&lt;li&gt;Basic CSS knowledge&lt;/li&gt;
&lt;li&gt;A text editor&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Create a Dockerfile
&lt;/h2&gt;

&lt;p&gt;First, create a &lt;code&gt;Dockerfile&lt;/code&gt; that extends the Open WebUI image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ghcr.io/open-webui/open-webui:git-49a928d&lt;/span&gt;

&lt;span class="c"&gt;# Optional: Replace favicon icons&lt;/span&gt;
&lt;span class="c"&gt;# COPY favicon.svg /app/build/static/favicon.svg&lt;/span&gt;
&lt;span class="c"&gt;# COPY favicon.png /app/build/static/favicon.png&lt;/span&gt;
&lt;span class="c"&gt;# COPY favicon.ico /app/build/static/favicon.ico&lt;/span&gt;

&lt;span class="c"&gt;# Copy your custom CSS file&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; custom.css /app/build/static/custom.css&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Always use a specific version tag (like &lt;code&gt;git-49a928d&lt;/code&gt;) instead of &lt;code&gt;main&lt;/code&gt; to ensure your theme doesn't break with updates. Check the &lt;a href="https://github.com/open-webui/open-webui/pkgs/container/open-webui" rel="noopener noreferrer"&gt;Open WebUI releases&lt;/a&gt; for available tags, especially if you need CUDA or Ollama support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create Your Custom CSS
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;custom.css&lt;/code&gt; file in the same directory as your Dockerfile. Here's an example theme with a blue and yellow color scheme:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--primary-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#00487d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffd600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--primary-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e2eef5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--hover-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#d4e3ed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#send-message-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#sidebar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-bg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#sidebar&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--hover-bg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;aria-label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"Voice mode"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.tippy-content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.tippy-box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"switch"&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="nt"&gt;aria-checked&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"true"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nc"&gt;.px-3&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nc"&gt;.py-1&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nc"&gt;.text-sm.font-medium.bg-black.hover&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nd"&gt;:bg-gray-900&lt;/span&gt;&lt;span class="nc"&gt;.text-white.dark&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nd"&gt;:bg-white&lt;/span&gt;&lt;span class="nc"&gt;.dark&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nd"&gt;:text-black&lt;/span&gt;&lt;span class="nc"&gt;.dark&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nd"&gt;:bg-gray-100&lt;/span&gt;&lt;span class="nc"&gt;.transition.rounded-full&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-yellow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Finding CSS Selectors
&lt;/h2&gt;

&lt;p&gt;To customize other elements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Open WebUI in your browser&lt;/li&gt;
&lt;li&gt;Right-click on the element you want to style&lt;/li&gt;
&lt;li&gt;Select "Inspect" or "Inspect Element"&lt;/li&gt;
&lt;li&gt;Find the appropriate CSS selector&lt;/li&gt;
&lt;li&gt;Add it to your &lt;code&gt;custom.css&lt;/code&gt; with &lt;code&gt;!important&lt;/code&gt; to override existing styles&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 4: Build and Run Your Custom Image
&lt;/h2&gt;

&lt;p&gt;Build your Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-custom-openwebui &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your themed Open WebUI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; open-webui:/app/backend/data &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; open-webui-custom &lt;span class="se"&gt;\&lt;/span&gt;
  my-custom-openwebui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The core functionality of Open WebUI hasn't changed. All normal configuration still applies!&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips and Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use CSS Variables&lt;/strong&gt;: Define colors as CSS variables for easy theme-wide changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Thoroughly&lt;/strong&gt;: Check all UI elements to ensure your theme doesn't break functionality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Specific Selectors&lt;/strong&gt;: Some elements may need very specific selectors due to Open WebUI's styling approach&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Control&lt;/strong&gt;: Keep your Dockerfile and custom.css in version control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document Your Changes&lt;/strong&gt;: Comment your CSS to remember what each override does&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;Want to deploy your custom-themed Open WebUI quickly? Check out our guide on &lt;a href="https://dev.to/sliplane/self-hosting-openwebui-ollama-the-easy-way"&gt;self-hosting OpenWebUI with Ollama&lt;/a&gt; which shows you how to deploy Open WebUI in minutes. Once deployed, you can easily update the container with your custom theme.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Creating custom themes for Open WebUI is straightforward once you understand the process. By injecting a custom CSS file into the Docker image, you can completely transform the look and feel of your Open WebUI instance. Remember to use specific version tags and test your themes thoroughly before deploying to production :)&lt;/p&gt;

&lt;p&gt;Happy theming!&lt;/p&gt;

&lt;p&gt;Jonas, Co-Founder of &lt;a href="https://sliplane.io?utm_source=theming-openwebui" rel="noopener noreferrer"&gt;sliplane.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>MCP Servers That I Use as a Technical Founder</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Sat, 26 Jul 2025 15:54:44 +0000</pubDate>
      <link>https://dev.to/code42cate/mcp-servers-that-i-use-as-a-technical-founder-3ia6</link>
      <guid>https://dev.to/code42cate/mcp-servers-that-i-use-as-a-technical-founder-3ia6</guid>
      <description>&lt;p&gt;There's been a flood of demos lately showing off how &lt;a href="https://github.com/modelcontextprotocol/servers" rel="noopener noreferrer"&gt;MCP servers&lt;/a&gt; can write WhatsApp messages or book plane tickets. Most of that feels like novelty, not utility. As a technical founder building &lt;a href="https://sliplane.io?utm_source=mcp-servers-founder" rel="noopener noreferrer"&gt;Sliplane&lt;/a&gt;, a Docker hosting platform, I live in my terminal, and I care about things that help me ship, support customers, and write content fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP?
&lt;/h2&gt;

&lt;p&gt;Quick refresher: MCP (Model Context Protocol) is &lt;a href="https://docs.anthropic.com/en/docs/build-with-claude/mcp" rel="noopener noreferrer"&gt;Anthropic's open protocol&lt;/a&gt; that lets AI assistants like Claude connect to external tools and data sources. Think of MCP servers as bridges that give Claude access to APIs, databases, or services. Instead of copy-pasting information back and forth, Claude can directly interact with your tools to get work done.&lt;/p&gt;

&lt;p&gt;Here are four MCP servers I actually use every day to get real work done. No gimmicks. Just productivity :)&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%2Fjdjpknnery159cpbsg93.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%2Fjdjpknnery159cpbsg93.png" alt="overview" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Docker Hub MCP Server
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For: Understanding and debugging third-party container images&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most &lt;a href="https://sliplane.io?utm_source=mcp-servers-founder" rel="noopener noreferrer"&gt;Sliplane&lt;/a&gt; users deploy prebuilt images from Docker Hub. But many issues come down to a single missing environment variable or a bad volume mount. When a customer asks for help with an obscure database or web app, I use the &lt;a href="https://github.com/modelcontextprotocol/servers/tree/main/src/dockerhub" rel="noopener noreferrer"&gt;Docker Hub MCP server&lt;/a&gt; to instantly pull the README and docs of that image.&lt;/p&gt;

&lt;p&gt;Instead of clicking around or copying commands from some badly formatted blog, I can just say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Get me the required environment variables plus the volume mount for &lt;code&gt;postgres&lt;/code&gt; from Docker Hub."&lt;/p&gt;
&lt;/blockquote&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%2Faehqn46tse3436cojibg.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%2Faehqn46tse3436cojibg.png" alt="DockerHub" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gets me 80% of the way to understanding the problem. It saves minutes per support ticket, and those add up fast when you're dealing with dozens per day.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. GitHub MCP Server
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For: Digging deeper into niche projects and edge cases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes the README isn't enough. Maybe the Docker image is outdated, or the docs are missing a config detail. That's when I use the &lt;a href="https://github.com/modelcontextprotocol/servers/tree/main/src/github" rel="noopener noreferrer"&gt;GitHub MCP server&lt;/a&gt;. It connects to the linked repo, looks at open issues, and can search for error messages or flags that aren't documented.&lt;/p&gt;

&lt;p&gt;For example, a user tried to use a specific node inside &lt;code&gt;n8n&lt;/code&gt; and there was no information about it. But with the GitHub MCP server, I searched through the issues and found a common thread that helped. That's the kind of context you don't get from static docs.&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%2F2v634tgjaxac9bvsaukz.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%2F2v634tgjaxac9bvsaukz.png" alt="Github" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Sliplane MCP Server
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For: Testing deployments directly, from chat&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After gathering the docs from Docker Hub and GitHub, I often hand off the problem to Claude, powered by a &lt;a href="https://docs.sliplane.io/mcp/getting-started/" rel="noopener noreferrer"&gt;Sliplane MCP server&lt;/a&gt; that wraps our API. It spins up a real server, deploys the container, collects logs, and tries to reason its way to a working setup. Yes, you're basically vibe coding cloud infra. Do it at your own risk :D&lt;/p&gt;

&lt;p&gt;This lets me treat deployment debugging as an interactive process. Claude can read logs and then automatically fix the deployment. It has a feedback loop that I don't need to control.&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%2Ftzk3ivggubsmfu08rszw.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%2Ftzk3ivggubsmfu08rszw.png" alt="Sliplane MCP" width="800" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It doesn't always get things perfect. But it gets me most of the way there while I move on to the next support ticket. I still talk to customers manually, but the underlying guesswork gets automated.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Dev.to MCP Server
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For: Publishing blog post drafts directly from Markdown&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once a weird issue is solved, I turn it into content. That's part of our growth loop at &lt;a href="https://sliplane.io?utm_source=mcp-servers-founder" rel="noopener noreferrer"&gt;Sliplane&lt;/a&gt;. I write Markdown posts like "&lt;a href="https://sliplane.io/blog/self-hosting-qdrant-with-docker-on-ubuntu-server" rel="noopener noreferrer"&gt;How to self-host Qdrant with Docker&lt;/a&gt;," and then use the &lt;a href="https://github.com/Arindam200/devto-mcp" rel="noopener noreferrer"&gt;inofficial Dev.to MCP server&lt;/a&gt; to create a draft on &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It doesn't publish the post automatically since I still tweak images and layout, but the draft is created with tags, title, and metadata pulled from the file. It's a small but useful automation that saves me time every week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use MCP servers?
&lt;/h2&gt;

&lt;p&gt;The real power isn't that Claude with MCP servers is necessarily faster than doing things manually. If I sat down and debugged a Docker deployment myself, I might even be quicker. But that's not the point. What I often do is specify the problem using speech-to-text, hand it off to Claude, and then move on to something else. Claude runs in the background, trying different approaches, reading docs, and debugging issues while I handle customer calls or write code. I can come back whenever I have time and see what progress was made. It's like having a junior developer who never gets tired and can work on the boring stuff while you focus on what matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;None of these are flashy. They don't write love poems or send Slack messages. But they help me support users, debug real deployments, and create useful content without leaving the terminal. &lt;a href="https://github.com/modelcontextprotocol/servers" rel="noopener noreferrer"&gt;MCP servers&lt;/a&gt; can be powerful. You just need to give them real work :D&lt;/p&gt;

&lt;p&gt;If you're interested in trying out MCP servers yourself, check out the &lt;a href="https://github.com/modelcontextprotocol/servers" rel="noopener noreferrer"&gt;official MCP repository&lt;/a&gt; for more examples and documentation. And if you need a place to host your Docker containers, give &lt;a href="https://sliplane.io?utm_source=mcp-servers-founder" rel="noopener noreferrer"&gt;Sliplane&lt;/a&gt; a try! Now that &lt;a href="https://docs.sliplane.io/mcp/getting-started/" rel="noopener noreferrer"&gt;you can vibe-code cloud infra&lt;/a&gt;, no excuse not to try to self-host!&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Jonas, Co-Founder &lt;a href="https://sliplane.io?utm_source=mcp-servers-founder" rel="noopener noreferrer"&gt;sliplane.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>llm</category>
      <category>startup</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Self-hosting Qdrant the easy way</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Sat, 12 Jul 2025 10:32:58 +0000</pubDate>
      <link>https://dev.to/code42cate/self-hosting-qdrant-the-easy-way-1h29</link>
      <guid>https://dev.to/code42cate/self-hosting-qdrant-the-easy-way-1h29</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/qdrant/qdrant" rel="noopener noreferrer"&gt;Qdrant&lt;/a&gt; is one of the most popular open-source vector databases for AI and semantic search applications. Whether you're building RAG applications, recommendation systems, or semantic search engines, Qdrant provides high-performance vector similarity search with advanced filtering capabilities.&lt;/p&gt;

&lt;p&gt;While the official Qdrant Cloud offering is convenient, it can get expensive fast, especially for production workloads. The good news? You can self-host Qdrant and get the same powerful features! In this tutorial, we'll show you how to deploy your own Qdrant instance on Sliplane for only &lt;strong&gt;€9 per month&lt;/strong&gt; with virtually no limitations and full control over your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Self-Host Qdrant?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost Savings&lt;/strong&gt;: Save 70%+ compared to managed solutions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Privacy&lt;/strong&gt;: Keep your vectors and metadata on your own infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full Control&lt;/strong&gt;: Configure Qdrant exactly how you need it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Vendor Lock-in&lt;/strong&gt;: Migrate your data anytime without restrictions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Easily upgrade your server as your needs grow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If you prefer watching a video, here is a 45 second guide on how to deploy Qdrant:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/1098997224" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Step-by-Step Deployment Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create Your Sliplane Account
&lt;/h3&gt;

&lt;p&gt;Sign up at &lt;a href="https://sliplane.io?utm_source=self-hosting-qdrant" rel="noopener noreferrer"&gt;sliplane.io&lt;/a&gt; for free. You can use your GitHub account for quick registration. New users get a 48-hour trial server to test everything out!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Set Up Your Server
&lt;/h3&gt;

&lt;p&gt;If you just signed up, you'll have a trial server ready to use. Otherwise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Servers&lt;/strong&gt; in your dashboard&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Server&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose the "Base" instance (2 vCPU, 2GB RAM) which is perfect for most Qdrant workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Deploy Qdrant Service
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to your project (create a new one or use the default)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Deploy Service&lt;/strong&gt; (top right corner)&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;Qdrant preset&lt;/strong&gt; from the available options&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Configure Security Settings
&lt;/h3&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Critical Step&lt;/strong&gt;: Before deploying, you'll see a random API key automatically generated in the environment variables. &lt;strong&gt;Save this API key immediately&lt;/strong&gt; as you'll need it to authenticate all requests to your Qdrant instance!&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Launch and Access
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Deploy&lt;/strong&gt; and wait for the service to start (usually takes 1-2 minutes)&lt;/li&gt;
&lt;li&gt;Once running, your Qdrant instance will be available at: &lt;code&gt;your-service-name.sliplane.app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The web UI will be accessible at: &lt;code&gt;https://your-service-name.sliplane.app/dashboard&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Test Your Connection
&lt;/h3&gt;

&lt;p&gt;You can quickly test your Qdrant instance using curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s1"&gt;'https://your-service-name.sliplane.app/collections'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'api-key: YOUR_SAVED_API_KEY'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get an empty collections response, confirming your instance is working!&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Comparison: Why Sliplane Wins
&lt;/h2&gt;

&lt;p&gt;Here's how Sliplane compares to other hosting options for running Qdrant:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Provider&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;vCPU&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;RAM&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Monthly Cost&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Setup Complexity&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Qdrant Cloud&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2 GB&lt;/td&gt;
&lt;td&gt;40 GB&lt;/td&gt;
&lt;td&gt;$29–$49&lt;/td&gt;
&lt;td&gt;⭐ Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS ECS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2 GB&lt;/td&gt;
&lt;td&gt;40 GB&lt;/td&gt;
&lt;td&gt;$40–$60&lt;/td&gt;
&lt;td&gt;⭐⭐⭐ Complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Render.com&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2 GB&lt;/td&gt;
&lt;td&gt;40 GB&lt;/td&gt;
&lt;td&gt;$35–$45&lt;/td&gt;
&lt;td&gt;⭐⭐ Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fly.io&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2 GB&lt;/td&gt;
&lt;td&gt;40 GB&lt;/td&gt;
&lt;td&gt;$20–$25&lt;/td&gt;
&lt;td&gt;⭐⭐ Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Railway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2 GB&lt;/td&gt;
&lt;td&gt;40 GB&lt;/td&gt;
&lt;td&gt;$15–$66*&lt;/td&gt;
&lt;td&gt;⭐⭐ Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sliplane&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2 GB&lt;/td&gt;
&lt;td&gt;40 GB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;€9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⭐ Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;*Railway charges based on actual usage. $66 is maximum possible cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Choose Sliplane?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Predictable Costs&lt;/strong&gt;: Flat €9/month with no usage surprises&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple Setup&lt;/strong&gt;: Deploy Qdrant in under 5 minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;European Hosting&lt;/strong&gt;: GDPR-compliant with excellent latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Included SSL&lt;/strong&gt;: HTTPS certificates automatically managed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Hidden Fees&lt;/strong&gt;: 2TB bandwidth included, transparent pricing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is self-hosted Qdrant the same as Qdrant Cloud?
&lt;/h3&gt;

&lt;p&gt;Self-hosted Qdrant gives you all the core features of the open-source version, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High-performance vector search&lt;/li&gt;
&lt;li&gt;Advanced filtering and hybrid search&lt;/li&gt;
&lt;li&gt;Clustering and replication&lt;/li&gt;
&lt;li&gt;REST and gRPC APIs&lt;/li&gt;
&lt;li&gt;Web dashboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Qdrant Cloud offers additional managed features like auto-scaling. For most use cases, self-hosting provides everything you need at a fraction of the cost. Check the &lt;a href="https://qdrant.tech/documentation/" rel="noopener noreferrer"&gt;official Qdrant documentation&lt;/a&gt; for feature comparisons.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are the bandwidth costs on Sliplane?
&lt;/h3&gt;

&lt;p&gt;Compute costs are &lt;strong&gt;always flat and predictable&lt;/strong&gt; with no surprises! You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2TB bandwidth included&lt;/strong&gt; in your €9/month plan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;€2/TB&lt;/strong&gt; for additional bandwidth (€14.8/TB in Singapore)&lt;/li&gt;
&lt;li&gt;No charges for CPU usage or memory consumption&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How do I update my Qdrant version?
&lt;/h3&gt;

&lt;p&gt;Updating is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If using the &lt;code&gt;latest&lt;/code&gt; tag: Click &lt;strong&gt;Redeploy&lt;/strong&gt; in your Sliplane dashboard&lt;/li&gt;
&lt;li&gt;For specific versions: Update the image tag in service settings and redeploy&lt;/li&gt;
&lt;li&gt;Your data persists across updates thanks to volume mounting&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Can I migrate from Qdrant Cloud to self-hosted?
&lt;/h3&gt;

&lt;p&gt;Yes! Qdrant provides built-in backup and restore functionality:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Export your collections using Qdrant's snapshot API&lt;/li&gt;
&lt;li&gt;Deploy your self-hosted instance on Sliplane&lt;/li&gt;
&lt;li&gt;Import your data using the restore API&lt;/li&gt;
&lt;li&gt;Update your application endpoints&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What if I need more resources?
&lt;/h3&gt;

&lt;p&gt;Sliplane makes scaling easy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vertical scaling&lt;/strong&gt;: Upgrade to larger instances (Medium: €24, Large: €44)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Horizontal scaling&lt;/strong&gt;: Deploy multiple Qdrant nodes with clustering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage expansion&lt;/strong&gt;: Add persistent volumes as needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Is my data secure?
&lt;/h3&gt;

&lt;p&gt;Absolutely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API key authentication&lt;/strong&gt; protects your instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS encryption&lt;/strong&gt; for all traffic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;European data centers&lt;/strong&gt; with GDPR compliance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private networking&lt;/strong&gt; between your services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Backups&lt;/strong&gt;  once per day&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Ready to deploy your own Qdrant instance? &lt;a href="https://sliplane.io?utm_source=self-hosting-qdrant" rel="noopener noreferrer"&gt;Sign up for Sliplane&lt;/a&gt; and have your vector database running in minutes!&lt;/p&gt;

&lt;p&gt;Need help with your deployment? Use our support chat (bottom right corner) or check out our &lt;a href="https://docs.sliplane.io" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more guides and tutorials.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>cloud</category>
      <category>devops</category>
    </item>
    <item>
      <title>Did Elon Musk just invent AGI? Everything you need to know about Grok 4 and how to try it out</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Thu, 10 Jul 2025 08:23:19 +0000</pubDate>
      <link>https://dev.to/code42cate/did-elon-musk-just-invent-agi-everything-you-need-to-know-about-grok-4-and-how-to-try-it-out-2p6m</link>
      <guid>https://dev.to/code42cate/did-elon-musk-just-invent-agi-everything-you-need-to-know-about-grok-4-and-how-to-try-it-out-2p6m</guid>
      <description>&lt;p&gt;Elon Musk’s AI company &lt;strong&gt;xAI&lt;/strong&gt; just dropped a bombshell: &lt;strong&gt;Grok 4&lt;/strong&gt; is here — and it’s fast, smart, and already topping the charts. Some even say its AGI.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1943158495588815072-471" src="https://platform.twitter.com/embed/Tweet.html?id=1943158495588815072"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1943158495588815072-471');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1943158495588815072&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Grok 4?
&lt;/h3&gt;

&lt;p&gt;Grok is xAI’s answer to ChatGPT, Claude, and Gemini. It's multi-modal, API-accessible, and now available in two flavors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Grok 4&lt;/strong&gt; (the base model)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grok 4 Heavy&lt;/strong&gt; (a multi-agent powerhouse that thinks in parallel)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;xAI says it performs &lt;em&gt;better than PhD level&lt;/em&gt; on academic tasks - Musk's words, not mine ;)&lt;/p&gt;




&lt;h3&gt;
  
  
  Benchmark showdown
&lt;/h3&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%2Fe1vwhl43c43rkqz3he8c.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%2Fe1vwhl43c43rkqz3he8c.png" alt="ARC AGI LEADERBOARD" width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Grok 4 is already outperforming most models in the wild:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benchmark&lt;/th&gt;
&lt;th&gt;Grok 4&lt;/th&gt;
&lt;th&gt;Grok 4 Heavy&lt;/th&gt;
&lt;th&gt;o3 (OpenAI)&lt;/th&gt;
&lt;th&gt;Gemini 2.5 Pro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Humanity’s Last Exam&lt;/strong&gt; (no tools)&lt;/td&gt;
&lt;td&gt;25.4%&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;21%&lt;/td&gt;
&lt;td&gt;21.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Humanity’s Last Exam&lt;/strong&gt; (with tools)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;44.4%&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;26.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ARC-AGI-2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;16.2%&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;~8%&lt;/td&gt;
&lt;td&gt;~6%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;🧠 That’s &lt;strong&gt;state-of-the-art&lt;/strong&gt; territory — especially the ARC-AGI score, nearly &lt;strong&gt;2x&lt;/strong&gt; the nearest competitor. Say what you want about Elon Musk, but that is impressive.&lt;/p&gt;




&lt;h3&gt;
  
  
  How much does it cost?
&lt;/h3&gt;

&lt;p&gt;Using Grok 4 via &lt;a href="https://openrouter.ai" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt; is easy — but not cheap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Grok 4&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input: &lt;code&gt;$3 / million tokens&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Output: &lt;code&gt;$15 / million tokens&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Compare that to OpenAI’s o3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input: &lt;code&gt;$2 / M&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Output: &lt;code&gt;$8 / M&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s also a $300/month &lt;strong&gt;SuperGrok Heavy&lt;/strong&gt; plan for early access to Grok 4 Heavy, new agents, coding models, and even video generation later this year.&lt;/p&gt;




&lt;h3&gt;
  
  
  Try Grok 4 via OpenRouter
&lt;/h3&gt;

&lt;p&gt;Want to test it yourself? Here’s a simple code snippet using &lt;a href="https://openrouter.ai" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://openrouter.ai/api/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;OPENROUTER_API_KEY&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;completion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-ai/grok-4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is in this image?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image_url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image_url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep, multimodal! &lt;strong&gt;Image in, answer out&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Final thoughts
&lt;/h3&gt;

&lt;p&gt;Between wild benchmark results and Musk’s usual hype, Grok 4 is shaping up to be a serious contender. Whether it holds up in the real world — or just on X.com — is still TBD.&lt;/p&gt;

&lt;p&gt;But if you want to play with what might be the &lt;strong&gt;most powerful public model today&lt;/strong&gt;, it’s already live via OpenRouter.&lt;/p&gt;

&lt;p&gt;Let’s see what it can do.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Jonas, Co-Founder of &lt;a href="https://sliplane.io?utm_source=xai-just-released-grok-4" rel="noopener noreferrer"&gt;sliplane.io&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://x.com/xai" rel="noopener noreferrer"&gt;xAI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/xai/status/1943158495588815072" rel="noopener noreferrer"&gt;Grok 4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openrouter.ai" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://techcrunch.com/2025/07/09/elon-musks-xai-launches-grok-4-alongside-a-300-monthly-subscription/" rel="noopener noreferrer"&gt;TechCrunch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>news</category>
      <category>tutorial</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Move Over LLaMA: Tencent's New Open LLM is Ready to Self-Host</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Sun, 29 Jun 2025 00:55:47 +0000</pubDate>
      <link>https://dev.to/code42cate/move-over-llama-tencents-new-open-llm-is-ready-to-self-host-a73</link>
      <guid>https://dev.to/code42cate/move-over-llama-tencents-new-open-llm-is-ready-to-self-host-a73</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/Tencent" rel="noopener noreferrer"&gt;Tencent&lt;/a&gt; just released a new open-source model called &lt;strong&gt;Hunyuan-A13B-Instruct&lt;/strong&gt;. It has open weights (not sure about code), and it runs locally (well if you have a B200 GPU). If you're curious about how it performs and want to try it out yourself, here's how to set it up on a rented GPU in a few minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Hunyuan-A13B?
&lt;/h2&gt;

&lt;p&gt;Hunyuan-A13B is a &lt;strong&gt;Mixture-of-Experts (MoE)&lt;/strong&gt; model with &lt;strong&gt;80 billion total parameters&lt;/strong&gt;, but only &lt;strong&gt;13 billion active&lt;/strong&gt; at a time. This means inference is much cheaper than a full dense model.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mixture-of-Experts (MoE) is a neural network architecture where only a subset of specialized "expert" sub-networks are activated for each input, reducing computation while increasing model capacity. A gating mechanism dynamically selects which experts to use based on the input, allowing the model to scale efficiently without always using all parameters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supports 256K context&lt;/strong&gt; out of the box&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fast and slow thinking modes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grouped Query Attention (GQA)&lt;/strong&gt; for more efficient inference&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent-oriented&lt;/strong&gt; tuning, with benchmark results on BFCL-v3 and τ-Bench&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quantization support&lt;/strong&gt;, including GPTQ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So far, it looks like a solid candidate for local experimentation, especially for long-context or agent-type tasks. I'm still testing how it compares to other models like LLaMA 3, Mixtral, and Claude 3.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Spin Up a RunPod Instance
&lt;/h2&gt;

&lt;p&gt;The easiest way to try it is &lt;a href="https://runpod.io?ref=36oe9u9g" rel="noopener noreferrer"&gt;RunPod&lt;/a&gt;(This link will give you between $5 and $500 credits!). You'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;300 GB network volume&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;B200 GPU&lt;/strong&gt; (I don't think less works, you need ~150GB of VRAM)&lt;/li&gt;
&lt;li&gt;A supported &lt;strong&gt;PyTorch image&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create a Network Volume
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Region: use one where B200 is available (currently &lt;code&gt;eu-ro-1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Size: 300 GB&lt;/li&gt;
&lt;li&gt;Cost: around &lt;strong&gt;$21/month&lt;/strong&gt; (billed even if unused)&lt;/li&gt;
&lt;/ul&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%2F6bstqukaq70q4abb0wsm.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%2F6bstqukaq70q4abb0wsm.png" alt="network" width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Pod
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GPU type: &lt;strong&gt;B200&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Image: &lt;code&gt;runpod/pytorch:2.8.0-py3.11-cuda12.8.1-cudnn-devel-ubuntu22.04&lt;/code&gt;&lt;br&gt;
⚠️ Earlier versions didn't work in my testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GPU Count: 1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable SSH + Jupyter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach your network volume&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Flqx3rx4z2vcnxkzobo81.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%2Flqx3rx4z2vcnxkzobo81.png" alt="gpu type" width="800" height="540"&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%2Fcdg9zxge6qplo23pe400.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%2Fcdg9zxge6qplo23pe400.png" alt="config" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Install Dependencies
&lt;/h2&gt;

&lt;p&gt;In the notebook terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%pip install transformers tiktoken accelerate gptqmodel optimum
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Load the Model
&lt;/h2&gt;

&lt;p&gt;Set the cache path so that downloads go to the mounted volume instead of the default root directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AutoModelForCausalLM&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HF_HOME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/workspace/hf-cache&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;#
&lt;/span&gt;&lt;span class="n"&gt;model_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tencent/Hunyuan-A13B-Instruct&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;tokenizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;local_files_only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trust_remote_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoModelForCausalLM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cache_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/workspace/hf-cache/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;local_files_only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device_map&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;torch_dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bfloat16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trust_remote_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What does the frog say?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;tokenized_chat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply_chat_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;return_tensors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                  &lt;span class="n"&gt;enable_thinking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt; &lt;span class="c1"&gt;# Toggle thinking mode (default: True)
&lt;/span&gt;                                              &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenized_chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;max_new_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;output_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First run will download ~150 GB of weights&lt;/li&gt;
&lt;li&gt;VRAM usage is ~153 GB during inference&lt;/li&gt;
&lt;li&gt;Loading into VRAM takes a few minutes&lt;/li&gt;
&lt;li&gt;If GPU util (not just VRAM) goes up, it's running&lt;/li&gt;
&lt;li&gt;You can set &lt;code&gt;device_map="cpu"&lt;/code&gt; if testing on CPU only. Make sure you have around 200GB of RAM and a good CPU :D&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Costs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;B200 pod: &lt;strong&gt;$6.39/hour&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Network volume: &lt;strong&gt;$21/month&lt;/strong&gt;, even if unused&lt;/li&gt;
&lt;li&gt;Suggestion: shut the pod down when not in use x)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tooling Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;llama.cpp&lt;/code&gt; support is not there yet. PR in progress: &lt;a href="https://github.com/ggml-org/llama.cpp/pull/14425" rel="noopener noreferrer"&gt;#14425&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Works fine in Python with &lt;code&gt;transformers&lt;/code&gt; and &lt;code&gt;bfloat16&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benchmark
&lt;/h2&gt;

&lt;p&gt;The official benchmarks are available on Hugging Face and evaluated by TRT-LLM-backend.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Hunyuan-Large&lt;/th&gt;
&lt;th&gt;Qwen2.5-72B&lt;/th&gt;
&lt;th&gt;Qwen3-A22B&lt;/th&gt;
&lt;th&gt;Hunyuan-A13B&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MMLU&lt;/td&gt;
&lt;td&gt;88.40&lt;/td&gt;
&lt;td&gt;86.10&lt;/td&gt;
&lt;td&gt;87.81&lt;/td&gt;
&lt;td&gt;88.17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MMLU-Pro&lt;/td&gt;
&lt;td&gt;60.20&lt;/td&gt;
&lt;td&gt;58.10&lt;/td&gt;
&lt;td&gt;68.18&lt;/td&gt;
&lt;td&gt;67.23&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MMLU-Redux&lt;/td&gt;
&lt;td&gt;87.47&lt;/td&gt;
&lt;td&gt;83.90&lt;/td&gt;
&lt;td&gt;87.40&lt;/td&gt;
&lt;td&gt;87.67&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BBH&lt;/td&gt;
&lt;td&gt;86.30&lt;/td&gt;
&lt;td&gt;85.80&lt;/td&gt;
&lt;td&gt;88.87&lt;/td&gt;
&lt;td&gt;87.56&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SuperGPQA&lt;/td&gt;
&lt;td&gt;38.90&lt;/td&gt;
&lt;td&gt;36.20&lt;/td&gt;
&lt;td&gt;44.06&lt;/td&gt;
&lt;td&gt;41.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EvalPlus&lt;/td&gt;
&lt;td&gt;75.69&lt;/td&gt;
&lt;td&gt;65.93&lt;/td&gt;
&lt;td&gt;77.60&lt;/td&gt;
&lt;td&gt;78.64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MultiPL-E&lt;/td&gt;
&lt;td&gt;59.13&lt;/td&gt;
&lt;td&gt;60.50&lt;/td&gt;
&lt;td&gt;65.94&lt;/td&gt;
&lt;td&gt;69.33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MBPP&lt;/td&gt;
&lt;td&gt;72.60&lt;/td&gt;
&lt;td&gt;76.00&lt;/td&gt;
&lt;td&gt;81.40&lt;/td&gt;
&lt;td&gt;83.86&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CRUX-I&lt;/td&gt;
&lt;td&gt;57.00&lt;/td&gt;
&lt;td&gt;57.63&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;70.13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CRUX-O&lt;/td&gt;
&lt;td&gt;60.63&lt;/td&gt;
&lt;td&gt;66.20&lt;/td&gt;
&lt;td&gt;79.00&lt;/td&gt;
&lt;td&gt;77.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MATH&lt;/td&gt;
&lt;td&gt;69.80&lt;/td&gt;
&lt;td&gt;62.12&lt;/td&gt;
&lt;td&gt;71.84&lt;/td&gt;
&lt;td&gt;72.35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CMATH&lt;/td&gt;
&lt;td&gt;91.30&lt;/td&gt;
&lt;td&gt;84.80&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;91.17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GSM8k&lt;/td&gt;
&lt;td&gt;92.80&lt;/td&gt;
&lt;td&gt;91.50&lt;/td&gt;
&lt;td&gt;94.39&lt;/td&gt;
&lt;td&gt;91.83&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPQA&lt;/td&gt;
&lt;td&gt;25.18&lt;/td&gt;
&lt;td&gt;45.90&lt;/td&gt;
&lt;td&gt;47.47&lt;/td&gt;
&lt;td&gt;49.12&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Hunyuan-A13B-Instruct has achieved highly competitive performance across multiple benchmarks, particularly in mathematics, science, agent domains, and more. We compared it with several powerful models, and the results are shown below. - Tencent&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Bench&lt;/th&gt;
&lt;th&gt;OpenAI-o1-1217&lt;/th&gt;
&lt;th&gt;DeepSeek R1&lt;/th&gt;
&lt;th&gt;Qwen3-A22B&lt;/th&gt;
&lt;th&gt;Hunyuan-A13B-Instruct&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mathematics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AIME 2024&lt;br&gt;AIME 2025&lt;br&gt;MATH&lt;/td&gt;
&lt;td&gt;74.3&lt;br&gt;79.2&lt;br&gt;96.4&lt;/td&gt;
&lt;td&gt;79.8&lt;br&gt;70&lt;br&gt;94.9&lt;/td&gt;
&lt;td&gt;85.7&lt;br&gt;81.5&lt;br&gt;94.0&lt;/td&gt;
&lt;td&gt;87.3&lt;br&gt;76.8&lt;br&gt;94.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Science&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GPQA-Diamond&lt;br&gt;OlympiadBench&lt;/td&gt;
&lt;td&gt;78&lt;br&gt;83.1&lt;/td&gt;
&lt;td&gt;71.5&lt;br&gt;82.4&lt;/td&gt;
&lt;td&gt;71.1&lt;br&gt;85.7&lt;/td&gt;
&lt;td&gt;71.2&lt;br&gt;82.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coding&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Livecodebench&lt;br&gt;Fullstackbench&lt;br&gt;ArtifactsBench&lt;/td&gt;
&lt;td&gt;63.9&lt;br&gt;64.6&lt;br&gt;38.6&lt;/td&gt;
&lt;td&gt;65.9&lt;br&gt;71.6&lt;br&gt;44.6&lt;/td&gt;
&lt;td&gt;70.7&lt;br&gt;65.6&lt;br&gt;44.6&lt;/td&gt;
&lt;td&gt;63.9&lt;br&gt;67.8&lt;br&gt;43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reasoning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;BBH&lt;br&gt;DROP&lt;br&gt;ZebraLogic&lt;/td&gt;
&lt;td&gt;80.4&lt;br&gt;90.2&lt;br&gt;81&lt;/td&gt;
&lt;td&gt;83.7&lt;br&gt;92.2&lt;br&gt;78.7&lt;/td&gt;
&lt;td&gt;88.9&lt;br&gt;90.3&lt;br&gt;80.3&lt;/td&gt;
&lt;td&gt;89.1&lt;br&gt;91.1&lt;br&gt;84.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Instruction&lt;br&gt;Following&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IF-Eval&lt;br&gt;SysBench&lt;/td&gt;
&lt;td&gt;91.8&lt;br&gt;82.5&lt;/td&gt;
&lt;td&gt;88.3&lt;br&gt;77.7&lt;/td&gt;
&lt;td&gt;83.4&lt;br&gt;74.2&lt;/td&gt;
&lt;td&gt;84.7&lt;br&gt;76.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Text&lt;br&gt;Creation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LengthCtrl&lt;br&gt;InsCtrl&lt;/td&gt;
&lt;td&gt;60.1&lt;br&gt;74.8&lt;/td&gt;
&lt;td&gt;55.9&lt;br&gt;69&lt;/td&gt;
&lt;td&gt;53.3&lt;br&gt;73.7&lt;/td&gt;
&lt;td&gt;55.4&lt;br&gt;71.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NLU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ComplexNLU&lt;br&gt;Word-Task&lt;/td&gt;
&lt;td&gt;64.7&lt;br&gt;67.1&lt;/td&gt;
&lt;td&gt;64.5&lt;br&gt;76.3&lt;/td&gt;
&lt;td&gt;59.8&lt;br&gt;56.4&lt;/td&gt;
&lt;td&gt;61.2&lt;br&gt;62.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;BDCL v3&lt;br&gt; τ-Bench&lt;br&gt;ComplexFuncBench&lt;br&gt; C3-Bench&lt;/td&gt;
&lt;td&gt;67.8&lt;br&gt;60.4&lt;br&gt;47.6&lt;br&gt;58.8&lt;/td&gt;
&lt;td&gt;56.9&lt;br&gt;43.8&lt;br&gt;41.1&lt;br&gt;55.3&lt;/td&gt;
&lt;td&gt;70.8&lt;br&gt;44.6&lt;br&gt;40.6&lt;br&gt;51.7&lt;/td&gt;
&lt;td&gt;78.3&lt;br&gt;54.7&lt;br&gt;61.2&lt;br&gt;63.5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is one of the more interesting open MoE models out right now. It supports long contexts, has some thoughtful design choices, and it's easy enough to run. I'm still evaluating how good it actually is, especially compared to Mistral Magistral and other recent models. If you want to test it yourself, this setup gets you going quickly.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Jonas, Co-Founder of &lt;a href="https://sliplane.io?utm_source=move-over-llama-tencent-open-llm-self-host" rel="noopener noreferrer"&gt;sliplane.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>news</category>
      <category>python</category>
    </item>
    <item>
      <title>Cloudflare just released Containers: here's everything you need to know</title>
      <dc:creator>Jonas Scholz</dc:creator>
      <pubDate>Wed, 25 Jun 2025 01:06:06 +0000</pubDate>
      <link>https://dev.to/code42cate/cloudflare-just-released-containers-heres-everything-you-need-to-know-26fi</link>
      <guid>https://dev.to/code42cate/cloudflare-just-released-containers-heres-everything-you-need-to-know-26fi</guid>
      <description>&lt;p&gt;Cloudflare Containers let you run &lt;strong&gt;any Docker image&lt;/strong&gt; on Cloudflare's 300-plus edge locations.&lt;br&gt;
You control them with a few lines of JavaScript in a Worker, they scale to zero, and you're billed in 10 ms slices while they're awake.&lt;/p&gt;

&lt;p&gt;They sit in the gap between:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Strengths&lt;/th&gt;
&lt;th&gt;Trade-offs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Workers (today)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sub-ms startup, worldwide&lt;/td&gt;
&lt;td&gt;V8 only, 128 MB RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Always-on PaaS (e.g. &lt;a href="https://sliplane.com?utm_source=cloudflare-containers" rel="noopener noreferrer"&gt;sliplane&lt;/a&gt;)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple, predictable&lt;/td&gt;
&lt;td&gt;You pay 24 / 7, even when idle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DIY Kubernetes / Fargate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full control at scale&lt;/td&gt;
&lt;td&gt;Cluster, LB, IAM overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cloudflare Containers bring the edge reach and pay-for-use pricing of Workers to workloads that need a full Linux sandbox.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why would I care?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Native binaries or full FS, so you can run FFmpeg, Pandas, or AI toolchains.&lt;/li&gt;
&lt;li&gt;Languages beyond JS or Wasm, such as Go, Rust, Python, Java, Ruby, or anything your Dockerfile holds.&lt;/li&gt;
&lt;li&gt;Bigger resource envelope, with up to 4 GiB RAM and half a vCPU per instance (larger sizes are planned).&lt;/li&gt;
&lt;li&gt;Per-tenant state, with one container per Durable-Object ID for sticky sessions.&lt;/li&gt;
&lt;li&gt;Burst-heavy jobs, such as cron, code evaluation, or on-demand video export.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your code sleeps a lot, scaling to zero is better than paying for an always-on container (whether that is &lt;a href="https://sliplane.com?utm_source=cloudflare-containers" rel="noopener noreferrer"&gt;sliplane&lt;/a&gt;, a VPS, or a managed dyno).&lt;/p&gt;




&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Scaffold + deploy&lt;/span&gt;
npm create cloudflare@latest &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;cloudflare/templates/containers-template
wrangler deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 2. Route requests in your Worker&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getRandom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@cloudflare/containers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;API&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;defaultPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;sleepAfter&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10m&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getRandom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// simple round-robin helper&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first hit is a cold-start (about 2 to 3 seconds in beta). After that, the container stays warm until it is idle for the duration set in &lt;code&gt;sleepAfter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Under the hood, each container is coupled to a Durable Object that handles lifecycle and routing. There is no YAML, no nodes, just code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pricing snapshot
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Meter (Workers Paid, $5/mo)&lt;/th&gt;
&lt;th&gt;Free quota&lt;/th&gt;
&lt;th&gt;Over-quota rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;25 GiB-hours&lt;/td&gt;
&lt;td&gt;$0.0000025 / GiB-s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPU&lt;/td&gt;
&lt;td&gt;375 vCPU-min&lt;/td&gt;
&lt;td&gt;$0.000020 / vCPU-s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disk&lt;/td&gt;
&lt;td&gt;200 GB-hours&lt;/td&gt;
&lt;td&gt;$0.00000007 / GB-s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Instance sizes in beta are dev (256 MiB), basic (1 GiB), and standard (4 GiB). Larger sizes are coming.&lt;/p&gt;

&lt;p&gt;Assume a "standard" instance (4 GiB RAM, half a vCPU, 4 GB disk) that runs 24 × 7 for a 30-day month and ships 2 TB of traffic. This is a workload better suited to an always-on PaaS.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Meter&lt;/th&gt;
&lt;th&gt;Raw usage&lt;/th&gt;
&lt;th&gt;Free quota&lt;/th&gt;
&lt;th&gt;Billable&lt;/th&gt;
&lt;th&gt;Rate&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;4 GiB × 2 592 000 s = &lt;strong&gt;10 368 000 GiB-s&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;25 GiB-h = 90 000 GiB-s&lt;/td&gt;
&lt;td&gt;10 278 000 GiB-s&lt;/td&gt;
&lt;td&gt;$0.0000025 / GiB-s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$25.70&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPU&lt;/td&gt;
&lt;td&gt;0.5 vCPU × 2 592 000 s = &lt;strong&gt;1 296 000 vCPU-s&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;375 vCPU-min = 22 500 vCPU-s&lt;/td&gt;
&lt;td&gt;1 273 500 vCPU-s&lt;/td&gt;
&lt;td&gt;$0.000020 / vCPU-s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$25.47&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disk (ephemeral)&lt;/td&gt;
&lt;td&gt;4 GB × 2 592 000 s = 10 368 000 GB-s&lt;/td&gt;
&lt;td&gt;200 GB-h = 720 000 GB-s&lt;/td&gt;
&lt;td&gt;9 648 000 GB-s&lt;/td&gt;
&lt;td&gt;$0.00000007 / GB-s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.68&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Egress (NA/EU)&lt;/td&gt;
&lt;td&gt;2 TB = 2048 GB&lt;/td&gt;
&lt;td&gt;1 TB&lt;/td&gt;
&lt;td&gt;1024 GB&lt;/td&gt;
&lt;td&gt;$0.025 / GB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$25.60&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Variable total: about $77.44 per month.&lt;br&gt;
Add the $5 Workers Paid subscription, and the total is about $82.44 all-in.&lt;/p&gt;

&lt;p&gt;A comparable always-on PaaS instance (such as sliplane or a small VPS) might cost $7 to $15 per month flat, so for high-utilisation, bandwidth-heavy services, Cloudflare Containers can be five to ten times more expensive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule of thumb: workloads that idle most of the day tend to cost less on Containers. Steady-state, high-utilisation services can still be cheaper on an always-on host like &lt;a href="https://sliplane.com?utm_source=cloudflare-containers" rel="noopener noreferrer"&gt;sliplane&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Current beta limits
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Manual scaling, you call &lt;code&gt;get(id)&lt;/code&gt;. Autoscale and latency routing are planned.&lt;/li&gt;
&lt;li&gt;Ephemeral disk, so you get a fresh FS after each sleep.&lt;/li&gt;
&lt;li&gt;40 GiB RAM and 20 vCPU account cap (temporary).&lt;/li&gt;
&lt;li&gt;Linux/amd64 only, no ARM support yet.&lt;/li&gt;
&lt;li&gt;No inbound TCP or UDP, since everything is proxied through a Worker HTTP call.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  When to pick Containers vs. an always-on PaaS
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Containers&lt;/th&gt;
&lt;th&gt;sliplane / always-on&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Edge-adjacent AI image generation, mostly idle&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24/7 REST API with over 70% utilisation&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ simpler, lower steady cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-tenant sandbox (one container per user)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database that needs persistent volumes&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A mixed model often wins. You can run your persistent database on sliplane (or similar), bursty compute on Cloudflare Containers, and connect them with a Worker.&lt;/p&gt;




&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Cloudflare just introduced what is essentially serverless Fargate at the edge: Docker images, millisecond billing, global points of presence, and no cluster busywork. If Workers' V8 box ever felt cramped, or your always-on container spends most of its time idle, try spinning up a beta Container and see what the edge can do.&lt;/p&gt;




&lt;p&gt;Happy hacking!&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Jonas, Co-Founder of &lt;a href="https://sliplane.com?utm_source=cloudflare-containers" rel="noopener noreferrer"&gt;sliplane&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>cloud</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
