<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[ Thoughts while building]]></title><description><![CDATA[A blog by Zsolt Ero on programming and building things.]]></description><link>https://blog.hyperknot.com</link><image><url>https://substackcdn.com/image/fetch/$s_!p1ro!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57e87a16-5ecc-4642-842f-3233254dc380_900x900.png</url><title> Thoughts while building</title><link>https://blog.hyperknot.com</link></image><generator>Substack</generator><lastBuildDate>Sun, 12 Apr 2026 20:37:23 GMT</lastBuildDate><atom:link href="https://blog.hyperknot.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Zsolt Ero]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[hyperknot@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[hyperknot@substack.com]]></itunes:email><itunes:name><![CDATA[Zsolt Ero]]></itunes:name></itunes:owner><itunes:author><![CDATA[Zsolt Ero]]></itunes:author><googleplay:owner><![CDATA[hyperknot@substack.com]]></googleplay:owner><googleplay:email><![CDATA[hyperknot@substack.com]]></googleplay:email><googleplay:author><![CDATA[Zsolt Ero]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[OpenFreeMap survived 100,000 requests per second]]></title><description><![CDATA[Sorry Wplace.live]]></description><link>https://blog.hyperknot.com/p/openfreemap-survived-100000-requests</link><guid isPermaLink="false">https://blog.hyperknot.com/p/openfreemap-survived-100000-requests</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Sat, 09 Aug 2025 13:30:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!7mXy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was about to post about how nice the last 10 months of <a href="https://openfreemap.org/">OpenFreeMap</a> have been. The architecture has really proven itself to be great, Cloudflare has agreed to sponsor the bandwidth, Hetzner servers are super stable as always, serving tiles from Btrfs proved to be a great choice, nginx is amazing, and life is good.</p><p>Then, out of the blue, I'm getting reports that some tiles are not loading, which normally means tile generation bugs, but not this time. I look into the nginx logs and see this:</p><pre><code>2025/08/08 23:08:16 [crit] 1084275#1084275: *161914910 open() "/mnt/ofm/planet-20250730_001001_pt/tiles/8/138/83.pbf" failed (24: Too many open files) ...</code></pre><p>This is weird. I've never seen anything like this. I check nload, and it shows huge traffic. I log into Cloudflare and I see <strong>THIS</strong> for the last 24 hours.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gPqG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gPqG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png 424w, https://substackcdn.com/image/fetch/$s_!gPqG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png 848w, https://substackcdn.com/image/fetch/$s_!gPqG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png 1272w, https://substackcdn.com/image/fetch/$s_!gPqG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gPqG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png" width="290" height="310.0936329588015" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1142,&quot;width&quot;:1068,&quot;resizeWidth&quot;:290,&quot;bytes&quot;:131535,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/170530219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gPqG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png 424w, https://substackcdn.com/image/fetch/$s_!gPqG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png 848w, https://substackcdn.com/image/fetch/$s_!gPqG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png 1272w, https://substackcdn.com/image/fetch/$s_!gPqG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb5b43d9f-e03e-4f4d-bb4a-f0f9005b5627_1068x1142.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>What? <strong>3 billion requests in 24 hours?</strong> What on Earth is that? Also, 215 TB of traffic from tiny, 70 kB files?</p><p>This much traffic would cost over $6 million per month on MapTiler and double that on Mapbox.</p><p>It's especially spiking in the last 5 minutes, where I'm seeing 30 million requests.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WPBx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WPBx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png 424w, https://substackcdn.com/image/fetch/$s_!WPBx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png 848w, https://substackcdn.com/image/fetch/$s_!WPBx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png 1272w, https://substackcdn.com/image/fetch/$s_!WPBx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WPBx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png" width="1456" height="1157" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1157,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:610511,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/170530219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WPBx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png 424w, https://substackcdn.com/image/fetch/$s_!WPBx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png 848w, https://substackcdn.com/image/fetch/$s_!WPBx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png 1272w, https://substackcdn.com/image/fetch/$s_!WPBx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33fd332a-1568-4e0c-bee3-2dcbb814739a_3756x2984.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>How much is that?</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5lZz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5lZz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png 424w, https://substackcdn.com/image/fetch/$s_!5lZz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png 848w, https://substackcdn.com/image/fetch/$s_!5lZz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png 1272w, https://substackcdn.com/image/fetch/$s_!5lZz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5lZz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png" width="526" height="61.41483516483517" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:170,&quot;width&quot;:1456,&quot;resizeWidth&quot;:526,&quot;bytes&quot;:146004,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/170530219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5lZz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png 424w, https://substackcdn.com/image/fetch/$s_!5lZz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png 848w, https://substackcdn.com/image/fetch/$s_!5lZz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png 1272w, https://substackcdn.com/image/fetch/$s_!5lZz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff28e69c0-a00e-4979-91af-eb769fff638a_2056x240.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Wow, that's <strong>100,000 requests per second</strong>!</p><p>My first thoughts are:</p><ul><li><p>Wow.</p></li><li><p>Wow, I'm surprised that the only bug I've heard about is some missing tiles. I mean, the service still seems to work? Somehow those empty tiles got cached by Cloudflare, but other than that, it still kind of works?</p></li></ul><p>Looking at the Cloudflare dashboard, I can see that 96% of the requests were 200 OK; only 3.6% were broken (206 Partial Content).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cwFU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cwFU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png 424w, https://substackcdn.com/image/fetch/$s_!cwFU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png 848w, https://substackcdn.com/image/fetch/$s_!cwFU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png 1272w, https://substackcdn.com/image/fetch/$s_!cwFU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cwFU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png" width="1456" height="182" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:182,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:178766,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/170530219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cwFU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png 424w, https://substackcdn.com/image/fetch/$s_!cwFU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png 848w, https://substackcdn.com/image/fetch/$s_!cwFU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png 1272w, https://substackcdn.com/image/fetch/$s_!cwFU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ecc692b-f6c4-4bf1-b729-05d4ee347938_3630x454.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>So it seems that OpenFreeMap is mostly managing to serve 100,000 requests per second?</p><h2><strong>But what is causing it?</strong></h2><p><a href="https://wplace.live/">Wplace.live</a> happened. Out of the blue, a new collaborative drawing website appeared, built from scratch using OpenFreeMap.</p><p>I don't know what it is, but the internet seems to be crazy about it. One thing is for sure: the traffic it generates is out of this world.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7mXy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7mXy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png 424w, https://substackcdn.com/image/fetch/$s_!7mXy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png 848w, https://substackcdn.com/image/fetch/$s_!7mXy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png 1272w, https://substackcdn.com/image/fetch/$s_!7mXy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7mXy!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png" width="1200" height="775.5494505494505" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:941,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:8817364,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/170530219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7mXy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png 424w, https://substackcdn.com/image/fetch/$s_!7mXy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png 848w, https://substackcdn.com/image/fetch/$s_!7mXy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png 1272w, https://substackcdn.com/image/fetch/$s_!7mXy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff834af0d-4b67-4b42-b0fb-5a1c49a12535_4000x2584.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://wplace.live/">Wplace.live</a></figcaption></figure></div><p>I believe what is happening is that those images are being drawn by some scripts. <s>If I understand correctly, the website limited everyone to 1 pixel per 30 seconds, so I guess everyone was just scripting Puppeteer/Chromium to start a new browser, click a pixel, and close the browser, possibly with IP address rotation, but maybe that wasn't even needed.</s> When you create a beautiful an image by hand, you are literally spending half an hour or more over the same map area, you don&#8217;t make map tile requests during this time.</p><p>Nice idea, interesting project, next time please contact me before. <a href="https://neal.fun/">Neal.fun</a> did the same before launching <a href="https://neal.fun/internet-roadtrip/">Internet Roadtrip</a> - they asked me if the traffic would be OK and even decided to sponsor the OpenFreeMap project with an amount that more than covers their bandwidth usage.</p><p>Sorry Wplace.live, I had to create my first-ever Cloudflare rule. As a single user, you broke the service for everyone.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cJrQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cJrQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png 424w, https://substackcdn.com/image/fetch/$s_!cJrQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png 848w, https://substackcdn.com/image/fetch/$s_!cJrQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png 1272w, https://substackcdn.com/image/fetch/$s_!cJrQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cJrQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png" width="385" height="151.83098591549296" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:504,&quot;width&quot;:1278,&quot;resizeWidth&quot;:385,&quot;bytes&quot;:77421,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/170530219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cJrQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png 424w, https://substackcdn.com/image/fetch/$s_!cJrQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png 848w, https://substackcdn.com/image/fetch/$s_!cJrQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png 1272w, https://substackcdn.com/image/fetch/$s_!cJrQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa54d2af9-d072-4ff5-9743-a1da2313c3a5_1278x504.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>I wonder if there is an automatic way to do this on Cloudflare, to limit traffic by referer or custom headers. It'd be great if this could be automatic, as I want to avoid this ever happening in the future. I hope I can script this via the API.</p><p>Finally, I want to say a huge thanks to Cloudflare for helping with the bandwidth. I haven't written about it yet, but when I contacted them back in November, they managed to get my bandwidth sponsorship status approved in 48 hours over a Saturday. Moreover, they connected me with some of their best engineers to discuss how OpenFreeMap could use their architecture even better. I've never seen a company of their size move as agilely as they did.</p><p>As the sole person running OpenFreeMap, I'm incredibly proud of these two numbers. First, that my architecture hit a 99.4% CDN cache rate, which is fantastic for a service with weekly data updates. And second, that my own servers successfully handled the remaining 1,000 requests per second. </p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ATGA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ATGA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png 424w, https://substackcdn.com/image/fetch/$s_!ATGA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png 848w, https://substackcdn.com/image/fetch/$s_!ATGA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png 1272w, https://substackcdn.com/image/fetch/$s_!ATGA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ATGA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png" width="226" height="121.136" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:268,&quot;width&quot;:500,&quot;resizeWidth&quot;:226,&quot;bytes&quot;:35267,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/170530219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ATGA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png 424w, https://substackcdn.com/image/fetch/$s_!ATGA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png 848w, https://substackcdn.com/image/fetch/$s_!ATGA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png 1272w, https://substackcdn.com/image/fetch/$s_!ATGA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35b950cd-6da7-4bcc-bfd3-5c2835e071e2_500x268.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2><strong>Update</strong></h2><p>I managed to contact the dev behind Wplace.live. He said they grew to 2 million users in a few days, out of the blue, so I totally understand them not being prepared for this kind of traffic. BTW, I'm amazed that their main architecture is holding up.</p><p>I offered to help them set up a self-hosted OpenFreeMap instance, which is the perfect fit for such use cases. They get the service for free, the public instance doesn't get the load, and everyone is happy.</p><p>Also, "only" having 2 million users confirms my belief that it's mostly scrips creating the load. 3 billion requests / 2 million users is an average of 1,500 req/user. A normal user might make 10-20 requests when loading a map and editing over one place for a long time, so some of these are extremely high, scripted use cases.<br><br>Also, this is literally the 1st Google result below the official website.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2RuW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2RuW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png 424w, https://substackcdn.com/image/fetch/$s_!2RuW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png 848w, https://substackcdn.com/image/fetch/$s_!2RuW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png 1272w, https://substackcdn.com/image/fetch/$s_!2RuW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2RuW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png" width="506" height="364.55631868131866" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1049,&quot;width&quot;:1456,&quot;resizeWidth&quot;:506,&quot;bytes&quot;:712937,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/170530219?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2RuW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png 424w, https://substackcdn.com/image/fetch/$s_!2RuW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png 848w, https://substackcdn.com/image/fetch/$s_!2RuW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png 1272w, https://substackcdn.com/image/fetch/$s_!2RuW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa19955fe-4f38-46b0-9c27-b9238f58276c_2936x2116.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>Learnings</strong></h3><p>There are two learnings I'll write about in a next post.</p><ol><li><p>I need to implement bandwidth limiting by referer. I'm looking into how to do this on Cloudflare. Nothing changes in the service; everything will still stay free and without registration, but every referer will be limited to a very high number, like 100 million requests per 24 hours or something similar. For native apps, I'll probably ask them to add a custom header identifying their app.</p></li><li><p>I'll need to improve my server config to fix those empty tiles. Even though I'm not expecting a load like this in the future, I think I found the culprit in the config that was causing the missing tiles.</p></li></ol><p>If you find OpenFreeMap valuable, please consider <a href="https://github.com/sponsors/hyperknot">sponsoring on GitHub</a>. To be fully transparent, the project currently runs on $500/month in donations. This is just enough to cover all infrastructure costs, which is fantastic. However, it means that new development happens in my limited free time. More support means more time I can spend coding, ensuring OpenFreeMap is ready for whatever comes next.</p><p>You can sponsor the project on GitHub at <a href="https://github.com/sponsors/hyperknot">https://github.com/sponsors/hyperknot</a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe to this blog, or follow me on <a href="https://x.com/hyperknot">X</a> or <a href="https://bsky.app/profile/hyperknot.com">Bluesky</a>.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Investigating AI Manipulation in Viral Chinese Paraglider Video]]></title><description><![CDATA[Update: news sites have pulled the video now, confirming parts of it were AI generated.]]></description><link>https://blog.hyperknot.com/p/investigating-ai-manipulation-in</link><guid isPermaLink="false">https://blog.hyperknot.com/p/investigating-ai-manipulation-in</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Fri, 30 May 2025 14:30:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/m-QMGysAXf0" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><strong>Update: news sites have <a href="https://deadline.com/2025/05/nbc-viral-chinese-paraglider-video-concerns-ai-generated-1236414202/#comments">pulled the video</a> now, confirming parts of it were AI generated.</strong></em></p><p>Right now, you might have read the news that a Chinese paraglider pilot, Peng Yujiang, got sucked into a cloud and ended up at 8,598 meters / 28,000 feet.</p><p>It's literally on every news website: <a href="https://edition.cnn.com/2025/05/29/asia/chinese-paraglider-survives-cctv-intl-latam">CNN</a>, <a href="https://www.bbc.com/news/articles/cm238175gzyo">BBC</a>, <a href="https://www.theguardian.com/world/2025/may/29/chinese-paraglider-peng-yujiang-survives-8000-metre-high-flight">The Guardian</a>.</p><p>Now, what makes this story really interesting is the accompanying video. Here is one version from The Guardian, which had 300k views in 17 hours: </p><div id="youtube2-m-QMGysAXf0" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;m-QMGysAXf0&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/m-QMGysAXf0?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>I've been paragliding for 18 years and follow the progress of AI very closely, but even I couldn't say with 100% certainty if this video is real or fake. </p><p>One scene is definitely fake: the one where the camera makes a move that would only be possible from a drone. In this scene, the otherwise black helmet is white, and the perspective falls apart in a strange, distorted way, typical of lower-quality AI-generated videos. Also, here, he is using a sitting harness (legs visible) whereas in the real ones, he is in a pod-style harness.</p><p>A screenshot from the fake scene:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aPpi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aPpi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png 424w, https://substackcdn.com/image/fetch/$s_!aPpi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png 848w, https://substackcdn.com/image/fetch/$s_!aPpi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png 1272w, https://substackcdn.com/image/fetch/$s_!aPpi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aPpi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png" width="338" height="377.7967741935484" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:693,&quot;width&quot;:620,&quot;resizeWidth&quot;:338,&quot;bytes&quot;:493443,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/164801517?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!aPpi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png 424w, https://substackcdn.com/image/fetch/$s_!aPpi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png 848w, https://substackcdn.com/image/fetch/$s_!aPpi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png 1272w, https://substackcdn.com/image/fetch/$s_!aPpi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F144ab880-43ef-404c-b21c-4d3ce962014a_620x693.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I think the other two scenes might be real though, recorded with a 360 camera on a selfie stick - a common setup for paragliding videos.</p><p>There are definitely some questions:</p><ul><li><p>Why did he (or someone) have to make a fake AI-generated scene and insert it between the two real ones (if they are indeed real)?</p></li><li><p>How does the camera move in both scenes, while his hands are definitely not moving it? In one scene, the camera makes a circular move, while in the other, it's moving away from the pilot slowly. I'm not saying it's impossible; I just don't yet understand what is moving the camera. Is the dolly-like move just a zoom effect? The resolution seems to remain the same.</p></li><li><p>Why is the camera not frozen at all? Everything is covered in thick ice, but somehow the camera's lens is not. (The phone's screen is also perfectly clear and ice-free.)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vjL3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vjL3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!vjL3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!vjL3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!vjL3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vjL3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1991327,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/164801517?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vjL3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!vjL3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!vjL3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!vjL3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52a5ff90-5f74-49f2-a0f2-f8af0166d81f_1920x1080.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p>To me, it seems like the pilot's face slightly changes between the two scenes. In one, he is a bit skinnier and paler; in the other, he is a bit more rounded and darker in color. Maybe the two scenes were recorded at different times?</p></li></ul><p>Looking closer at the equipment, we can conclude that this is indeed the case. He is using a different harness with a different setup in the two scenes.</p><p>In one scene he has a phone with a glossy screen (left arrow), whereas in the second image, he has a plastic power bank.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JoMf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JoMf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png 424w, https://substackcdn.com/image/fetch/$s_!JoMf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png 848w, https://substackcdn.com/image/fetch/$s_!JoMf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png 1272w, https://substackcdn.com/image/fetch/$s_!JoMf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JoMf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png" width="470" height="496.33053221288515" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1508,&quot;width&quot;:1428,&quot;resizeWidth&quot;:470,&quot;bytes&quot;:1448651,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/164801517?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JoMf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png 424w, https://substackcdn.com/image/fetch/$s_!JoMf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png 848w, https://substackcdn.com/image/fetch/$s_!JoMf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png 1272w, https://substackcdn.com/image/fetch/$s_!JoMf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e467d2a-5f78-46b3-970f-a146361a0894_1428x1508.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ATBb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ATBb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png 424w, https://substackcdn.com/image/fetch/$s_!ATBb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png 848w, https://substackcdn.com/image/fetch/$s_!ATBb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png 1272w, https://substackcdn.com/image/fetch/$s_!ATBb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ATBb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png" width="477" height="408.65991316931985" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:592,&quot;width&quot;:691,&quot;resizeWidth&quot;:477,&quot;bytes&quot;:667054,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/164801517?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ATBb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png 424w, https://substackcdn.com/image/fetch/$s_!ATBb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png 848w, https://substackcdn.com/image/fetch/$s_!ATBb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png 1272w, https://substackcdn.com/image/fetch/$s_!ATBb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff626d414-c338-4a5e-b4c3-d8dd63a4f1d1_691x592.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Also, the harness is different: one has shiny metal connectors (right arrow), the other has orange straps.</p><p>So we can definitely conclude that these two scenes were recorded at different times.</p><h3>What is the origin of this video? </h3><p>Here is a <a href="https://www.youtube.com/results?search_query=chinese+paraglider&amp;sp=CAI%253D">YouTube search page</a> for "Chinese paraglider" - ordered by upload date.</p><p>The <a href="https://www.youtube.com/watch?v=8QMLSLQYMPI">oldest version</a> is from 4 days ago, interestingly from the possible <a href="https://www.yowfly.com/product/paragliding-gloves/">manufacturer</a> of the hand-warming "mittens" he is using. Maybe the whole idea came from the manufacturer?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2W72!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2W72!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png 424w, https://substackcdn.com/image/fetch/$s_!2W72!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png 848w, https://substackcdn.com/image/fetch/$s_!2W72!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png 1272w, https://substackcdn.com/image/fetch/$s_!2W72!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2W72!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png" width="1456" height="827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:827,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3464876,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/164801517?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2W72!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png 424w, https://substackcdn.com/image/fetch/$s_!2W72!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png 848w, https://substackcdn.com/image/fetch/$s_!2W72!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png 1272w, https://substackcdn.com/image/fetch/$s_!2W72!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe018aeae-efcc-4e96-a4e2-c7773d66700a_4044x2296.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>After that, there is this YouTube Short, which, to me, looks like the best-quality footage so far.</p><div id="youtube2-SIOZBR5pprc" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;SIOZBR5pprc&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/SIOZBR5pprc?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Afterwards, AI-generated fake scenes start to be mixed into the videos, which in turn are copied by all major news outlets.</p><p>Even the <a href="https://xcmag.com/news/pilot-swept-to-8500m-in-china-survives/">No. 1 paragliding magazine</a> is linking to one such video, whereas it should be obvious to every paraglider pilot that it contains AI-generated scenes.</p><p>Don't worry too much about the articles saying he just accidentally got "caught" up in the cloud; this was a super-well-planned and carefully executed flight. He, of course, has to say this; otherwise, he'd get in even bigger trouble with the authorities.</p><p>Additionally, it appears that this is a mechanical altimeter. Paraglider pilots typically never use such instruments because our electronic devices are much more precise, more lightweight and function reliably at the altitudes and temperatures we normally encounter. This particular gauge is a bulky, industrial-style metal instrument, specially carried for these record attempts.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X115!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X115!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png 424w, https://substackcdn.com/image/fetch/$s_!X115!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png 848w, https://substackcdn.com/image/fetch/$s_!X115!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png 1272w, https://substackcdn.com/image/fetch/$s_!X115!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X115!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png" width="1456" height="507" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:507,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1922515,&quot;alt&quot;:&quot;Metal altitude gauge&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.hyperknot.com/i/164801517?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Metal altitude gauge" title="Metal altitude gauge" srcset="https://substackcdn.com/image/fetch/$s_!X115!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png 424w, https://substackcdn.com/image/fetch/$s_!X115!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png 848w, https://substackcdn.com/image/fetch/$s_!X115!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png 1272w, https://substackcdn.com/image/fetch/$s_!X115!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26382d9b-a018-4939-b8a8-335e3490bf2f_2276x792.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Mechanical altimeter</figcaption></figure></div><h3>How is it possible to do this? Wouldn't someone lose consciousness before reaching those altitudes?</h3><p>Yes, most people would lose consciousness long before reaching such altitudes. However, Sherpas can climb Mount Everest without supplemental oxygen, even while performing intense physical activity. Therefore, I don't see why a suitably adapted person couldn't reach the same altitude, comfortably seated in a paragliding harness.</p><p>So, to answer some of my questions, I believe:</p><ul><li><p>The video contains three scenes: one is 100% AI-generated, one is from an older attempt, and one is from the current flight.</p></li><li><p>The dolly effect in the current flight might be AI-generated, but the footage is real. The linked YouTube Short is definitely original footage.</p></li><li><p>I believe the pilot definitely made the flight, and it was planned long in advance, possibly over many months or even years. He might even have had a sponsor from the mitten manufacturer.</p></li><li><p>Interestingly, in that climate, all glass surfaces stayed clear of frost, so the camera had a perfect picture. I mean, airplane windows also don't get icy from the outside, so it's possible that glass just stays 100% clear in that environment.</p></li><li><p>It's a pity that an AI-generated scene got mixed into the video, as well as an older recording. If not for this, the footage would have been authentic.</p></li></ul><p>The real story, however, might be how major media outlets shared this as authentic footage, yet the AI-generated portion looks laughably fake by today's standards.</p><p>But here's what's truly concerning: what we consider state-of-the-art AI generation today will look just as crude in twelve months. AI video quality makes massive leaps every year. If news outlets already struggle with primitive AI content, how will they cope when the technology becomes perfect?</p><p>For finish, below are some videos possible with today&#8217;s latest model, Google&#8217;s Veo 3.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe to this blog</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h4>Bonus: current state-of-the-art AI video samples</h4><p>Emotional support kangaroo not allowed on airplane</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;805c1cd2-ba9e-493f-9eb1-ef76f56209a4&quot;,&quot;duration&quot;:null}"></div><p>Prompt theory</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;4e14bddd-10bb-4692-8c3a-af98bf45b2b2&quot;,&quot;duration&quot;:null}"></div><p>By @<a href="https://x.com/emollick/status/1927117736179589631">emollick</a></p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;54d19602-b744-40a0-bd5b-59fc42b459ae&quot;,&quot;duration&quot;:null}"></div><p>By <a href="https://x.com/PJaccetturo/status/1925464847900352590">@PJaccetturo</a></p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;3502601a-fae7-41a7-bea0-7e842e8c6ea9&quot;,&quot;duration&quot;:null}"></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe to this blog</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p></p><p></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[The curious case of the packageManager field in package.json]]></title><description><![CDATA[Today I Learned]]></description><link>https://blog.hyperknot.com/p/corepacks-packagemanager-field</link><guid isPermaLink="false">https://blog.hyperknot.com/p/corepacks-packagemanager-field</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Sun, 29 Dec 2024 01:39:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!NHqJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><strong>TLDR</strong></em>: If you run into issues with the packageManager field in JS projects, you have to set COREPACK_ENABLE_AUTO_PIN to 0 in your bash profile <em>and</em> remove the existing packageManager field from your package.jsons. </p><div><hr></div><p>In my experience, package.json was a stable, proven system that worked. Then came corepack's introduction of adding <strong>packageManager</strong> in each package.json, even when no one asked for it, for example when simply running &#8220;pnpm i&#8221;.</p><p>The idea is that to enforce reproducibility, you have to pin not just your packages, but also your package manager - and not just to a major version, but right down to the patch version.</p><p>In a kind of micro-management style, node/corepack now takes control from the package managers. Instead of trusting them not to break reproducibility, they introduce "phantom" package managers based on which directory you're in.</p><p>So for example, if I run:</p><pre><code>$HOME/.nvm/versions/node/v20.17.0/bin/pnpm --version</code></pre><p>it reports "9.10.0" when I'm in one folder and "9.15.2" when I'm in another directory. This totally breaks how "bin" files are supposed to work on UNIX/Linux/macOS. One "bin" file should equal one version.<br><br>So what&#8217;s in the file? It seems to be a wrapper calling corepack.cjs:</p><pre><code>#!/usr/bin/env node
process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT??='1'
require('./lib/corepack.cjs').runMain(['pnpm', ...process.argv.slice(2)]);</code></pre><p>Unfortunately corepack.cjs is a unreadable/bundled file, so it&#8217;s not easy to figure out what&#8217;s happening inside.</p><p>They added a possible way to turn this behaviour off (set COREPACK_ENABLE_AUTO_PIN to 0), but hid it in an ENV var, so it cannot be set in a repo - it has to be set on each contributor's machine. The <a href="https://github.com/nodejs/corepack/issues/485">first Google result</a> for this COREPACK_ENABLE_AUTO_PIN env var is a GitHub issue, explaining why the default setting breaks open-source workflows, as each contributor is required to disable it in their local environment - it cannot be configured on repo level.</p><p>Moreover it's broken. Every time I run &#8220;pnpm i&#8221;, it annoys me to upgrade pnpm:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NHqJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NHqJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png 424w, https://substackcdn.com/image/fetch/$s_!NHqJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png 848w, https://substackcdn.com/image/fetch/$s_!NHqJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png 1272w, https://substackcdn.com/image/fetch/$s_!NHqJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NHqJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png" width="1456" height="463" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:463,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:239675,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NHqJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png 424w, https://substackcdn.com/image/fetch/$s_!NHqJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png 848w, https://substackcdn.com/image/fetch/$s_!NHqJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png 1272w, https://substackcdn.com/image/fetch/$s_!NHqJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec6743c8-b3eb-4c84-837a-4f26073f0c21_2298x730.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Except, when I run the displayed command:</p><pre><code>corepack install -g pnpm@9.15.2</code></pre><p>it does nothing. It definitely doesn't update the packageManager field in my package.json, so my project is always left on the old version. This means that tomorrow, it can tell me again that "Update is available!"</p><p>The confusing thing is that the update notice links to pnpm&#8217;s GitHub and even to their X page. There's not a single mention that its corepack which is artificially keeping back the package manager's version.</p><p>I opened a thread on pnpm where they recommended me to turn off this behavior of corepack. Which is basically the only choice they have, as corepack is breaking this system above their head and then users report thinking that pnpm is broken.</p><p></p><h4>GitHub links</h4><p>Open source maintainers explaining why it's not working (29 upvotes) <a href="https://github.com/nodejs/corepack/issues/485">https://github.com/nodejs/corepack/issues/485</a></p><p>My issue for pnpm trying to figure out what's happening: <a href="https://github.com/orgs/pnpm/discussions/8911">https://github.com/orgs/pnpm/discussions/8911</a></p><p>My issue for corepack: <a href="https://github.com/nodejs/corepack/issues/587">https://github.com/nodejs/corepack/issues/587</a></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe to this blog, or follow me on <a href="https://x.com/hyperknot">X</a> or <a href="https://bsky.app/profile/hyperknot.com">Bluesky</a>.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><br></p><p></p>]]></content:encoded></item><item><title><![CDATA[2nd stage of the AI age: AI Labs Need Your Data]]></title><description><![CDATA[First stage of the "AI age" was getting inference costs down to "too cheap to meter".]]></description><link>https://blog.hyperknot.com/p/ai-labs-need-your-data</link><guid isPermaLink="false">https://blog.hyperknot.com/p/ai-labs-need-your-data</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Thu, 19 Dec 2024 01:56:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>First stage of the "AI age" was getting inference costs down to "too cheap to meter".</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0R-6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0R-6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png 424w, https://substackcdn.com/image/fetch/$s_!0R-6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png 848w, https://substackcdn.com/image/fetch/$s_!0R-6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!0R-6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0R-6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png" width="1456" height="571" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:571,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:363461,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0R-6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png 424w, https://substackcdn.com/image/fetch/$s_!0R-6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png 848w, https://substackcdn.com/image/fetch/$s_!0R-6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!0R-6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F818c76ed-724f-4874-9bee-490f955dafaf_2610x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><blockquote><p>Cost of AI models:</p><ul><li><p>Training time: a one-time, 3-month-long process costing up to a billion dollars</p></li><li><p>Inference time: when you ask questions in your favorite chat app. The cost of this is converging to a fraction of a cent.</p></li></ul></blockquote><p></p><div><hr></div><p></p><h4><strong>The second stage of the AI age</strong> is all about your data</h4><p>Ilya Sutskever announced in a <a href="https://www.youtube.com/watch?v=1yvBqasHLZs">NeurIPS talk</a>, that AI labs are running out of data, "The fossil fuel of AI".</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!R9WQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!R9WQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png 424w, https://substackcdn.com/image/fetch/$s_!R9WQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png 848w, https://substackcdn.com/image/fetch/$s_!R9WQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png 1272w, https://substackcdn.com/image/fetch/$s_!R9WQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!R9WQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png" width="486" height="335.46016483516485" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1005,&quot;width&quot;:1456,&quot;resizeWidth&quot;:486,&quot;bytes&quot;:1391142,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!R9WQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png 424w, https://substackcdn.com/image/fetch/$s_!R9WQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png 848w, https://substackcdn.com/image/fetch/$s_!R9WQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png 1272w, https://substackcdn.com/image/fetch/$s_!R9WQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd3e58d2b-847b-454b-ba2a-ac57ce6d949d_3380x2332.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>"We have but one internet" - the data on the internet is limited (also meaning that they've already scraped whatever they could).</p><p>In light of this, some of the recent announcements by the companies behind the AI labs make immediate sense.</p><p></p><div><hr></div><p></p><p></p><p><strong>Microsoft</strong> is <a href="https://github.com/features/copilot/plans">offering Copilot for free</a>, previously $20 per month (still a loss leader even at that price!). The catch: in all plans under $19 per month, they are training on your data by default.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!V08P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!V08P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png 424w, https://substackcdn.com/image/fetch/$s_!V08P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png 848w, https://substackcdn.com/image/fetch/$s_!V08P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png 1272w, https://substackcdn.com/image/fetch/$s_!V08P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!V08P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png" width="1456" height="383" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:383,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:372132,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!V08P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png 424w, https://substackcdn.com/image/fetch/$s_!V08P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png 848w, https://substackcdn.com/image/fetch/$s_!V08P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png 1272w, https://substackcdn.com/image/fetch/$s_!V08P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66de2dab-ca1e-4e46-bb49-23f7f4c89e01_4056x1066.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><p></p><p></p><p><strong>Google</strong> releases <a href="https://blog.google/technology/google-deepmind/google-gemini-ai-update-december-2024/">Gemini 2.0 Flash</a>, one of the most advanced models ever, with real-time audio and video-streaming input! And if that's not enough, you get it entirely free on Google AI Studio and through the API!</p><p>The catch? When you use the Free version, Google <a href="https://ai.google.dev/gemini-api/terms#data-use-unpaid">uses your data for model training</a>. At least they clearly point out that you should not submit "sensitive, confidential, or personal information to the Unpaid Services".</p><p>(Also, can anyone point out how to access the non-Free version? I really tried but couldn't find how. Do you need a Google Cloud account for that?)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nJpn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nJpn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png 424w, https://substackcdn.com/image/fetch/$s_!nJpn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png 848w, https://substackcdn.com/image/fetch/$s_!nJpn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png 1272w, https://substackcdn.com/image/fetch/$s_!nJpn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nJpn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png" width="1456" height="459" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:459,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:733020,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nJpn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png 424w, https://substackcdn.com/image/fetch/$s_!nJpn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png 848w, https://substackcdn.com/image/fetch/$s_!nJpn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png 1272w, https://substackcdn.com/image/fetch/$s_!nJpn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d64449d-94fb-4a74-954a-fa6666ec6757_3556x1120.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><div><hr></div><p></p><p></p><p><strong>OpenAI</strong> is offering previous premium features, like <a href="https://www.youtube.com/watch?v=OzgNJJ2ErEE">Search</a>, to all users, even those on the Free plan. They really want to see Google dance. (Meanwhile, Google makes them dance with the <a href="https://deepmind.google/technologies/veo/veo-2/">Veo 2 video model</a> - it's really fun to watch.)</p><p>They also now give Free users a <a href="https://help.openai.com/en/articles/8400625-voice-mode-faq">monthly allowance</a> of "Advanced voice mode" and have even started 1-800-ChatGPT, a <a href="https://help.openai.com/en/articles/10193193-1-800-chatgpt-calling-and-messaging-chatgpt-with-your-phone">free phone line</a> where you can talk with ChatGPT!</p><p>The catch? You guessed it - for all consumer plans (aka not Teams or Enterprise), your data is <a href="https://help.openai.com/en/articles/7039943-data-usage-for-consumer-services-faq">used for model training</a>. Ironically, this seems to include even the new $200/month Pro plan!</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_RyJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_RyJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png 424w, https://substackcdn.com/image/fetch/$s_!_RyJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png 848w, https://substackcdn.com/image/fetch/$s_!_RyJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png 1272w, https://substackcdn.com/image/fetch/$s_!_RyJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_RyJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png" width="568" height="148.63186813186815" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:381,&quot;width&quot;:1456,&quot;resizeWidth&quot;:568,&quot;bytes&quot;:284385,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_RyJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png 424w, https://substackcdn.com/image/fetch/$s_!_RyJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png 848w, https://substackcdn.com/image/fetch/$s_!_RyJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png 1272w, https://substackcdn.com/image/fetch/$s_!_RyJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff661997b-d42e-426f-8d81-4202d28b7b55_2570x672.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><p></p><p>One company surprisingly missing from the last 2 weeks' series of announcements was <strong>Anthropic</strong>, which happens to be the only company that is <a href="https://support.anthropic.com/en/articles/8325621-i-would-like-to-input-sensitive-data-into-free-claude-ai-or-claude-pro-who-can-view-my-conversations">not training on your data</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jNto!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jNto!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png 424w, https://substackcdn.com/image/fetch/$s_!jNto!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png 848w, https://substackcdn.com/image/fetch/$s_!jNto!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png 1272w, https://substackcdn.com/image/fetch/$s_!jNto!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jNto!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png" width="568" height="314.81868131868134" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:807,&quot;width&quot;:1456,&quot;resizeWidth&quot;:568,&quot;bytes&quot;:623940,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jNto!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png 424w, https://substackcdn.com/image/fetch/$s_!jNto!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png 848w, https://substackcdn.com/image/fetch/$s_!jNto!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png 1272w, https://substackcdn.com/image/fetch/$s_!jNto!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bccfdfa-744c-4360-8bf5-d2fefb762b80_2692x1492.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>They seem to be taking a different direction compared to other players, and they also happen to have the best model for coding! Claude Sonnet is actually so good that Microsoft was forced to <a href="https://x.com/GergelyOrosz/status/1867555882034245671">start offering it in GitHub Copilot</a>; otherwise, developers would have left the platform.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9l02!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9l02!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png 424w, https://substackcdn.com/image/fetch/$s_!9l02!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png 848w, https://substackcdn.com/image/fetch/$s_!9l02!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png 1272w, https://substackcdn.com/image/fetch/$s_!9l02!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9l02!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png" width="572" height="616.7857142857143" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1570,&quot;width&quot;:1456,&quot;resizeWidth&quot;:572,&quot;bytes&quot;:3268573,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9l02!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png 424w, https://substackcdn.com/image/fetch/$s_!9l02!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png 848w, https://substackcdn.com/image/fetch/$s_!9l02!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png 1272w, https://substackcdn.com/image/fetch/$s_!9l02!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F025481da-cdc6-4bb4-82eb-3d09e823360a_2668x2876.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><p></p><p></p><p>It's wonderful to watch a dance of titans, who are outbidding each other while offering loss-making products for free. Just remember to stay aware of how they handle your data and which providers/plans actually respect your privacy.</p><p>Also, to be entirely honest, there might be other reasons for offering these products for free. For example, by offering CoPilot for free, Microsoft overnight decided the fate of dozens of "coding assistance" startups. The chances of a new "Cursor" being started in 2025 just got quite a bit slimmer.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe to this blog</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><div><hr></div><p></p><p>I&#8217;ve also written 3 TIL posts since the last newsletter.</p><p></p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;f41346fd-c09d-406f-84bd-bb2c28e1f61b&quot;,&quot;caption&quot;:&quot;I spent a day learning about CSS-in-JS solutions for SolidJS. I looked for performant/compile-time solutions. Quick summary:&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;md&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;TIL: CSS-in-JS modules for SolidJS&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:121308039,&quot;name&quot;:&quot;Zsolt Ero&quot;,&quot;bio&quot;:&quot;Founder of http://maphub.net\n\nLoves building.\n\nWebsite: http://hyperknot.com&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4493a04-aa03-4863-92e4-6875f8db25fe_512x512.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-11-27T12:26:26.812Z&quot;,&quot;cover_image&quot;:null,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.hyperknot.com/p/til-css-in-js-modules-for-solidjs&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:152236380,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot; Thoughts while building&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57e87a16-5ecc-4642-842f-3233254dc380_900x900.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;aa1284f7-5ac5-458b-9f22-d23ed57930fb&quot;,&quot;caption&quot;:&quot;I was looking for a simple universal JS lib that could handle OpenAI/Anthropic/Google responses without having to install each client lib. Considering all these do is JSON requests, those client libs are actually quite big - for example, OpenAI is 87 kB on its own (bundled with Vite), though Google is only 25 kB.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;md&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;TIL: Vercel AI SDK - the bloat king&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:121308039,&quot;name&quot;:&quot;Zsolt Ero&quot;,&quot;bio&quot;:&quot;Founder of http://maphub.net\n\nLoves building.\n\nWebsite: http://hyperknot.com&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4493a04-aa03-4863-92e4-6875f8db25fe_512x512.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-12-11T15:27:13.932Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.hyperknot.com/p/til-vercel-ai-sdk-the-bloat-king&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:152967225,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot; Thoughts while building&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57e87a16-5ecc-4642-842f-3233254dc380_900x900.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;b2c399fb-9337-441d-9294-c2d12c034141&quot;,&quot;caption&quot;:&quot;Seeing which files are being processed by linter tools is surprisingly difficult. A common use case is when you're trying to debug why your linter is taking ages, and you discover it's trying to lint bundled JS files.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;TIL: Get file list from eslint, biome and ruff&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:121308039,&quot;name&quot;:&quot;Zsolt Ero&quot;,&quot;bio&quot;:&quot;Founder of http://maphub.net\n\nLoves building.\n\nWebsite: http://hyperknot.com&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4493a04-aa03-4863-92e4-6875f8db25fe_512x512.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-12-18T09:51:31.978Z&quot;,&quot;cover_image&quot;:null,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.hyperknot.com/p/til-get-file-list-from-eslint-biome&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:153303688,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot; Thoughts while building&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57e87a16-5ecc-4642-842f-3233254dc380_900x900.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div>]]></content:encoded></item><item><title><![CDATA[TIL: Get file list from eslint, biome and ruff]]></title><description><![CDATA[Seeing which files are being processed by linter tools is surprisingly difficult.]]></description><link>https://blog.hyperknot.com/p/til-get-file-list-from-eslint-biome</link><guid isPermaLink="false">https://blog.hyperknot.com/p/til-get-file-list-from-eslint-biome</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Wed, 18 Dec 2024 09:51:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!p1ro!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57e87a16-5ecc-4642-842f-3233254dc380_900x900.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Seeing which files are being processed by linter tools is surprisingly difficult. A common use case is when you're trying to debug why your linter is taking ages, and you discover it's trying to lint bundled JS files.</p><p>Here are the shortest commands I could come up with for eslint and biome:</p><h4>eslint</h4><pre><code>eslint --debug 2&gt;&amp;1 | grep /repo | sed 's|.*/repo||' | sort -u</code></pre><h4>biome</h4><pre><code><s>biome check --colors=off --log-level=info --log-kind=pretty . | grep 'path' | sed 's|.*\./||' | sort -u</s></code></pre><p>update: biome recently added file listing to the verbose flag, so it can be simplified to:</p><pre><code>biome check --verbose</code></pre><p>For Python, ruff supports a flag (--show-files), but only for "check", not for the "format" command:</p><h4>ruff</h4><pre><code>ruff check --fix --show-files . // works
ruff format --show-files . // doesn&#8217;t work</code></pre><p>Why do these tools make it so difficult to see this information? Prettier shows it by default on every run - not even a flag is needed.</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[TIL: Vercel AI SDK - the bloat king]]></title><description><![CDATA[I was looking for a simple universal JS lib that could handle OpenAI/Anthropic/Google responses without having to install each client lib.]]></description><link>https://blog.hyperknot.com/p/til-vercel-ai-sdk-the-bloat-king</link><guid isPermaLink="false">https://blog.hyperknot.com/p/til-vercel-ai-sdk-the-bloat-king</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Wed, 11 Dec 2024 15:27:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!xu69!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was looking for a simple universal JS lib that could handle OpenAI/Anthropic/Google responses without having to install each client lib. Considering all these do is JSON requests, those client libs are actually quite big - for example, OpenAI is 87 kB on its own (bundled with Vite), though Google is only 25 kB.</p><p>From what I've seen, there's one universal library from Vercel called AI SDK. It has 870k weekly downloads on NPM and a fancy package name: just "ai" (I wonder how much that one cost).</p><p>It's split into 2 packages, and the "Core" one sounds promising! So how much does this "Core" add to the bundle when using it for just a single OpenAI request?</p><p>A whopping 186 kB! For a tool that simply calls an OpenAI endpoint. What is basically just a JSON request.</p><p>I really don't get Vercel and the whole ecosystem they built with VC money. Everything they do is the most overcomplicated, architecture-astronaut level stuff. Like here, just the "packages" subdir is 73 thousand lines of code. For a JSON API wrapper!</p><p>I mean, the "bad guys" story would be: let's create extremely bloated JS libs so that you'll pick our solutions which allow you to run these on our servers. But I really don't think this is the case - it's just that Vercel's company culture is all about overcomplicating everything.</p><p>I've read from many devs that you choose Vercel for the amazing DX, but I just really don't see that DX. Luckily, I haven't had to refactor Next.js codebases every year, but even from what I've seen, everything they do is the opposite of great DX.</p><p>Anyway, back to my original quest - I haven't found any minimalistic, universal JS lib that supports streaming from multiple providers, so I'll be writing it myself using the low-level "eventsource-parser" lib.</p><p>Has anyone found anything for this purpose?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xu69!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xu69!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png 424w, https://substackcdn.com/image/fetch/$s_!xu69!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png 848w, https://substackcdn.com/image/fetch/$s_!xu69!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png 1272w, https://substackcdn.com/image/fetch/$s_!xu69!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xu69!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png" width="1456" height="799" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:799,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:410933,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xu69!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png 424w, https://substackcdn.com/image/fetch/$s_!xu69!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png 848w, https://substackcdn.com/image/fetch/$s_!xu69!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png 1272w, https://substackcdn.com/image/fetch/$s_!xu69!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44ebe37d-dd48-4762-bfe7-edbaa23b5bbf_1476x810.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[TIL: CSS-in-JS modules for SolidJS]]></title><description><![CDATA[I spent a day learning about CSS-in-JS solutions for SolidJS.]]></description><link>https://blog.hyperknot.com/p/til-css-in-js-modules-for-solidjs</link><guid isPermaLink="false">https://blog.hyperknot.com/p/til-css-in-js-modules-for-solidjs</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Wed, 27 Nov 2024 12:26:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!p1ro!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57e87a16-5ecc-4642-842f-3233254dc380_900x900.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I spent a day learning about CSS-in-JS solutions for SolidJS. I looked for performant/compile-time solutions. Quick summary:</p><p>1. Inline styling is really painful to type in SolidJS, as it uses "margin-bottom" instead of marginBottom. You need to type the quotes and dashes, and there's no autocomplete. Meanwhile, your competitor wrote "mb-2" in Tailwind.</p><p>2. Tailwind has the highest performance, with absolutely no runtime, but I just prefer real CSS.</p><p>3. CSS modules doesn't allow me to write CSS next to my components. For tiny components/helper utilities, I don't want to write two files. Also, CSS modules is runtime only, meaning slower performance.</p><p>4. vanilla-extract is like CSS modules but compile-time and super fast. Still, it requires writing everything in separate files.</p><p>5. Then comes Panda CSS - I lost a day trying to make it work. It has perfect SolidJS support, but it's the single most overcomplicated CSS solution I've ever seen in my life. It's like Kubernetes for CSS. Moreover, simply adding it to a project totally overtakes its CSS into a "design system" and introduces 14 kB of minified CSS! It also adds a whopping 51 kB of runtime JS! For a library that's supposed to be a compile-time CSS solution, this is crazy.</p><p>I chose it because I like Ark UI and it has a matching Panda styled "Park UI", but I just ended up having really bad feelings about how Panda would work in a long-term project. What I wanted was a simple CSS-in-JS solution for setting styles on components; what I got was a super complicated system that tells me how to do everything in their "design system".</p><p>Case in point, removing the border around the Accordion component from Park UI was so complicated that I ended up asking about it on their Discord. The "copy your component to simply modify it" approach is totally broken here. Any other solution (Radix UI, shadcn, SolidUI, etc.) would have allowed me to tweak the rule in no time.</p><p>6. "macaron" is recommended on the SolidJS docs site, but it's done by a single person, Google knows nothing about it, and it doesn't even work.</p><p>7. Solid Styled Components and Solid Styled JSX have no commits in 2 years. Also, that Styled JSX syntax is really not pretty. Both of them are runtime only too.</p><p>8. Pigment CSS/linaria doesn't support SolidJS.</p><p>9. In the end, I went with styleX by Facebook. It's minimalistic, unlike Panda, allows using the same file for JSX and CSS, and is actually extremely fast! Its full runtime code is only 6 kB, and you can see from the quality of the repo that Facebook has been using this in production for 5+ years. Also, it works with SolidJS, which is a surprise from the creators of React.</p><p>10. So styleX it is - I'm very happy with the minimal approach it takes. I only wanted to type some styles in JS, and that's exactly what it allows. It doesn't want to introduce a "design system", doesn't want to change the way I write code; it just stays in the background and generates atomic CSS classes at compile time.</p>]]></content:encoded></item><item><title><![CDATA[TIL: Auth provider updates]]></title><description><![CDATA[Today I learned: not yet a full post, just sharing what I learned]]></description><link>https://blog.hyperknot.com/p/til-auth-provider-updates</link><guid isPermaLink="false">https://blog.hyperknot.com/p/til-auth-provider-updates</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Tue, 12 Nov 2024 21:35:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zMbw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yesterday I read from Simon Willison that if I have more than 10 tabs open for solving a problem, then I should post about it. So after about 100 tabs open, I'll start posting about my quest for auth providers.</p><p><strong>Background 1</strong>: 1.5 years ago <a href="https://blog.hyperknot.com/p/comparing-auth-providers">I wrote an article</a> about it.</p><p><strong>Background 2</strong>: Back then I invested quite some time into using Next.js and modern React, but soon after I wrote the article, this Next.js + modern React combo became the most disillusioning experience in my software developer career. I think I really don't get Vercel; it's supposed to be amazing DX for a lot of money, but I honestly found it the worst and most confusing overcomplicated DX for a lot of money. I think Vercel is single-handedly the reason for the renaissance of HTMX / FastHTML / Hotwire / LiveView frameworks. Which is actually quite good for the ecosystem!</p><p><strong>Background 3</strong>: I'm trying to figure out how I can offer Enterprise SSO for $300 per month plans on a SaaS product, which is 10-20 times smaller than where it's usually offered.</p><div><hr></div><p>What would I use today?</p><p>1. A separate backend API in any language the developer prefers. For example, for AI projects, writing the backend in Python makes a lot of sense.</p><p>2. Splitting the frontend into app subdomain and home page / "marketing" website. Marketing website can be a static site in a CloudFlare bucket. I really like <a href="https://astro.build/">Astro</a> for this part. The tricky part is the pricing page, which can depend on local currency, IP address, etc.</p><p>3. The app lives on its subdomain, like app.myproject.com, which requires login. This one can be a classic SPA created with Vite. No need to overcomplicate anything, it's a breath of fresh air to see a classic SPA after battling Next.js's bizarre server/client magic.</p><p>One bonus advantage of this system is that Google only sees the marketing website, so we don't get penalized on SEO for any technical or UX choice we make on the app subdomain.</p><div><hr></div><p>Now, what happened on the auth landscape in the last 1.5 years? First of all, there are so many auth providers now that it's impossible to count them all. Michael Grinich, the CEO of WorkOS listed 31 on the <a href="https://news.ycombinator.com/item?id=41926639">HN discussion</a> of my article here, but even then he missed a few.</p><p>Almost all the providers I wrote about in my article changed pricing. I don't mean just a little bit, but they totally rethought their pricing structure/logic. It is probably my biggest worry about recommending closed-source vendors, that with auth you are at the ultimate vendor lock-in and the vendor can just decide to refactor their pricing model any time.</p><p>On the positive side, many limitations I wrote about in that article got fixed. For example, Supabase added 2FA and fixed some bugs, ZITADEL added nice examples and worked a bit on the UI.</p><div><hr></div><p><a href="https://www.ory.sh/">Ory</a> totally moved up-market and is now expensive and open-core. Price for 10k users is $1600 per month. Self-hosting is not an option anymore, as the open-source version doesn't support SAML orgs for example.</p><p>Also, they have some really weird hard-coded behavior, like when changing email address, you need to verify both the old and the new email address. In my life, I've experienced this behavior maybe once, and that was on a bank account. Literally no SaaS vendor asks you to verify your old email address. The reason you want to change it in the first place is probably because you no longer have access to your old email! </p><p>All in all, I no longer recommend Ory.</p><div><hr></div><p><a href="https://clerk.com/">Clerk</a> is super focused on the JS ecosystem, especially Next.js. It's lacking SDKs and examples for other languages. </p><p>Moreover, they ask $125 for MFA, which I find super baffling; it reminds me of those web hosts who asked for money to have HTTPS even many years after Let's Encrypt existed. MFA is one of the reasons people go with dedicated auth providers, don't sell it for $125!</p><p>I no longer recommend Clerk.</p><div><hr></div><p><a href="https://fusionauth.io/">FusionAuth</a> is closed-source and they offer a limited version for self-hosting. Their pricing is super confusing. </p><p>To get the full package, like SCIM, it costs $3300 per month for 10k users and you even need to self-host it!</p><div><hr></div><p><a href="https://boxyhq.com/">BoxyHQ</a> offers a really interesting open-core model, with the super geekily named SAML Jackson (it takes a while, try to say it out loud). </p><p>I found their product to be the most promising for adding SCIM or Enterprise SSO onto an existing auth setup. It's not yet clear how these combined products work. I mean they offer the SSO login while you are already using some kind of auth system, how do you handle sessions? Do you code two, independent session handling mechanisms into your app? That sounds super bug prone.</p><p>If not, then how do you combine your existing auth provider with BoxyHQ? I see that they offer some sample apps with Supertokens for example, but I don't yet understand the general logic here. If you know how these mix-of-two-provider auth systems work, can you explain it? It seems very bug prone to me.</p><div><hr></div><p><a href="https://workos.com/">WorkOS</a> is super good! They are a serious company, which used to offer only Enterprise-related features, and recently started offering "normal" auth, like password or social login. </p><p>They have the easiest to use website and examples in many languages. It's still early stage for their product though; for example, changing emails is still a work-in-progress. I wouldn't worry about it too much, as if you start developing a product now, then by the time you ship and get traction this feature is probably shipped. </p><p>Also, the best part is that they offer 1 million monthly active users for free! Basically their pricing model is you get everything you need for B2C websites for free, and you pay premium money for enterprise SSO / SAML / SCIM.</p><p>With that said, I arrived at their biggest limitation: the enterprise SSO with directory sync / SCIM costs $250 per month per customer. At which point you have to ask the question how much "auth tax" can you afford per customer? If the answer is say 5%, then you need $5000+ per monthly plans. Which is a very realistic scenario for their bigger customers, but definitely not for all companies.</p><p>Having said that, if you don't need SSO / SCIM then I think there is almost no question, the best solution is to use WorkOS! I mean it's the perfect choice for 99% of B2C apps, and is totally free!</p><div><hr></div><p>And what if you do need those features? For example, what can you do if your customers require enterprise SSO / SAML on a $300 plan? You look for cheaper offers or self-host.</p><p><a href="https://supabase.com/">Supabase</a> is one of those cheaper offers, offering SAML on their $25 Pro plan! What's confusing is <a href="https://supabase.com/docs/guides/platform/sso/gsuite">this page</a> in their docs, which says that you need the $600 per month plan.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zMbw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zMbw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png 424w, https://substackcdn.com/image/fetch/$s_!zMbw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png 848w, https://substackcdn.com/image/fetch/$s_!zMbw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png 1272w, https://substackcdn.com/image/fetch/$s_!zMbw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zMbw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png" width="436" height="154.64375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:454,&quot;width&quot;:1280,&quot;resizeWidth&quot;:436,&quot;bytes&quot;:59105,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zMbw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png 424w, https://substackcdn.com/image/fetch/$s_!zMbw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png 848w, https://substackcdn.com/image/fetch/$s_!zMbw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png 1272w, https://substackcdn.com/image/fetch/$s_!zMbw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15ecdaa1-aa65-4768-b106-4ec79772867e_1280x454.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Also, it's not clear if any of these advanced features are available in the self-hosted version, or it's tied to their hosted offerings.</p><div><hr></div><p>Right now I'm checking out self-hosting <a href="https://zitadel.com/">ZITADEL</a>. </p><p>Previously I wrote that the configuration is very complicated, which is still true today, but luckily they added nice documentation, example projects and even videos about how to set up auth for the most common scenarios. For example React frontend + Python backend is one of their examples!</p><p>I'll write about ZITADEL as I work through it. They are one of the few truly open-source companies in the auth space, and one of the very few solutions offering open-source Enterprise SSO / SAML! Their whole product is open-source and is shipped in a Docker container, so it's relatively easy to self-host!</p><p>But first, a comment about their pricing for the hosted version. They give the pricing on Daily Active Users (DAU), which is calculated in the weirdest way. It's so weird that their first 2 FAQ items are trying to explain it! Basically it's saying that if a single user checks your site every day, then it counts as 30 daily active users. It sounds like the craziest thing to me. For me this seems like 1 user, definitely not 30. Is this normal to count daily users like this elsewhere?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QVOE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QVOE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png 424w, https://substackcdn.com/image/fetch/$s_!QVOE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png 848w, https://substackcdn.com/image/fetch/$s_!QVOE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png 1272w, https://substackcdn.com/image/fetch/$s_!QVOE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QVOE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png" width="1456" height="886" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:886,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:398315,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QVOE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png 424w, https://substackcdn.com/image/fetch/$s_!QVOE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png 848w, https://substackcdn.com/image/fetch/$s_!QVOE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png 1272w, https://substackcdn.com/image/fetch/$s_!QVOE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6701688d-9dde-4bd2-a56e-fc554629355a_2294x1396.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Also, doesn't it just push developers to set a really long refresh timeout, as users are counted when a refresh token is issued? I mean, if they are pushing developers to use less secure environments, then what's the point of choosing a dedicated auth provider in the first place? Isn't the whole point of security is to have reasonable duration refresh tokens, which can be revoked if needed?</p><p>Anyway, they really have the best open-source offering and if you self-host then the pricing totally doesn't matter!</p><div><hr></div><p>That's what I've learned in the last 2 days. If I wrote something that isn't correct, or if you can help me with some of my questions, or if you just feel like commenting, please leave a comment below.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe. You can also follow me on <a href="https://x.com/hyperknot">X</a> or <a href="https://bsky.app/profile/hyperknot.com">Bluesky</a>.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Understanding Round Robin DNS]]></title><description><![CDATA[In which I try to understand how browsers and Cloudflare choose which server to use]]></description><link>https://blog.hyperknot.com/p/understanding-round-robin-dns</link><guid isPermaLink="false">https://blog.hyperknot.com/p/understanding-round-robin-dns</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Sat, 26 Oct 2024 12:29:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CPx_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For <a href="https://openfreemap.org/">OpenFreeMap</a>, I'm using servers behind Round Robin DNS. In this article, I'm trying to understand how browsers and CDNs select which one to use.</p><h2>What is Round Robin DNS?</h2><p>Normally, when you are serving a website from a VPS like Digital Ocean or Hetzner, you add a single A record in your DNS provider's control panel.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fFw4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fFw4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png 424w, https://substackcdn.com/image/fetch/$s_!fFw4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png 848w, https://substackcdn.com/image/fetch/$s_!fFw4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png 1272w, https://substackcdn.com/image/fetch/$s_!fFw4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fFw4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png" width="414" height="75.46875" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15591e83-689a-4821-8309-919e0528a434_768x140.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:140,&quot;width&quot;:768,&quot;resizeWidth&quot;:414,&quot;bytes&quot;:12808,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fFw4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png 424w, https://substackcdn.com/image/fetch/$s_!fFw4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png 848w, https://substackcdn.com/image/fetch/$s_!fFw4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png 1272w, https://substackcdn.com/image/fetch/$s_!fFw4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15591e83-689a-4821-8309-919e0528a434_768x140.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>This means that rr-direct.hyperknot.com will serve data from 5.223.46.55.</p><p>In Round Robin DNS, you specify multiple servers for the same subdomain, like this.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vmvY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vmvY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png 424w, https://substackcdn.com/image/fetch/$s_!vmvY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png 848w, https://substackcdn.com/image/fetch/$s_!vmvY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png 1272w, https://substackcdn.com/image/fetch/$s_!vmvY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vmvY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png" width="416" height="140.76767676767676" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:268,&quot;width&quot;:792,&quot;resizeWidth&quot;:416,&quot;bytes&quot;:26869,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vmvY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png 424w, https://substackcdn.com/image/fetch/$s_!vmvY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png 848w, https://substackcdn.com/image/fetch/$s_!vmvY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png 1272w, https://substackcdn.com/image/fetch/$s_!vmvY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c97e110-0b2c-429b-b764-acb2331afa7e_792x268.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>This allows you to share the load between multiple servers, as well as to automatically detect which servers are offline and choose the online ones.</p><p>It's an amazingly simple and elegant solution that avoids using Load Balancers. It's also free, and you can do it on any DNS provider, whereas Load Balancing solutions can get really expensive (even on Cloudflare, which is otherwise very reasonably priced).</p><h2>How does it work in theory?</h2><p>I became obsessed with how it works. I mean, on the surface, everything is elegant, but how does a browser decide which server to connect to?</p><p>In theory, there is an <a href="https://datatracker.ietf.org/doc/html/rfc8305">RFC 8305</a> called Happy Eyeballs (also linking to <a href="https://datatracker.ietf.org/doc/html/rfc6724#section-6">RFC 6724</a>) about how the client should sort addresses before connecting.</p><p>Now, this is definitely above my experience level,&nbsp;but <a href="https://datatracker.ietf.org/doc/html/rfc8305#section-4">this section</a>&nbsp;seems like the closest to answering my question:</p><blockquote><p>If the client is stateful and has a history of expected round-trip times (RTTs) for the routes to access each address, it SHOULD add a Destination Address Selection rule between rules 8 and 9 that prefers addresses with lower RTTs.</p></blockquote><p>So in my understanding, it's basically:</p><ul><li><p>Checking if servers are online/offline</p></li><li><p>Sort the online ones according to ping times</p></li></ul><h2>In Practice</h2><p>Let's see how it works in practice.</p><p>I created 3 VPSs around the world: one in the US, one in the EU, and one in Singapore. I made 3 proxied and 3 non-proxied A records in Cloudflare.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CPx_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CPx_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png 424w, https://substackcdn.com/image/fetch/$s_!CPx_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png 848w, https://substackcdn.com/image/fetch/$s_!CPx_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png 1272w, https://substackcdn.com/image/fetch/$s_!CPx_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CPx_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png" width="470" height="204.48566610455313" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:516,&quot;width&quot;:1186,&quot;resizeWidth&quot;:470,&quot;bytes&quot;:70975,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CPx_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png 424w, https://substackcdn.com/image/fetch/$s_!CPx_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png 848w, https://substackcdn.com/image/fetch/$s_!CPx_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png 1272w, https://substackcdn.com/image/fetch/$s_!CPx_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F13e623d8-a8c8-44e9-ad80-0e61b53323f6_1186x516.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>They run nginx with a config like this:</p><pre><code>server {
    server_name rr-direct.hyperknot.com rr-cf.hyperknot.com;

    # this is basically a wildcard block
    # so /a/b/c will return the same color.png file
    location / {
        root /data;
        rewrite ^ /color.png break;
    }

    location /server {
        alias /etc/hostname;
        default_type text/plain;
    }
}</code></pre><p>So they serve a color.png, which is a 1px red/green/blue PNG file, as well as their hostname, which is test-eu/us/sg.</p><h3>Client Behavior When Servers Are Online</h3><p><a href="https://assets.openfreemap.com/share/2024-10/rr.html">I made a HTML test page</a>, which fills a 10x10 grid with random images.</p><p>The server colors are the following:</p><ul><li><p>US - green</p></li><li><p>EU - blue</p></li><li><p>SG - red</p></li></ul><p>Important: I'm testing from Europe; the EU server is much closer to me than US or especially the SG one. I should be seeing blue boxes!</p><h4>Chrome</h4><p>Chrome selects somewhat randomly between all locations, but once selected, it sticks with it. It re-evaluates the selection after a few hours. In this case, it was stuck with SG for hours, even though it is by far the slowest server for me.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bze4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bze4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!bze4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!bze4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!bze4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bze4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png" width="404" height="240.3757828810021" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82985913-6f42-4fd2-b009-61fedac5294f_958x570.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:958,&quot;resizeWidth&quot;:404,&quot;bytes&quot;:20708,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bze4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!bze4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!bze4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!bze4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82985913-6f42-4fd2-b009-61fedac5294f_958x570.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Also, an interesting behavior on Chrome was when not using HTTP/2: it can sometimes choose randomly between two servers, creating a pattern like this. Here it's choosing between EU and US randomly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OGiQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OGiQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!OGiQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!OGiQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!OGiQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OGiQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png" width="406" height="241.56576200417535" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:958,&quot;resizeWidth&quot;:406,&quot;bytes&quot;:21271,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OGiQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!OGiQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!OGiQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!OGiQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c86eaa-335c-4ceb-af52-e4db28fefcf4_958x570.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Firefox</h4><p>Behaves similarly to Chrome, selects a location randomly on startup and then sticks with it. If I restart the browser, it picks a different random location.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!q2ZX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q2ZX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!q2ZX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!q2ZX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!q2ZX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q2ZX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png" width="432" height="257.035490605428" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:958,&quot;resizeWidth&quot;:432,&quot;bytes&quot;:20653,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!q2ZX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!q2ZX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!q2ZX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!q2ZX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67cfbcbe-87f8-4d83-a46e-a970b4f34fd7_958x570.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Safari</h4><p>To my biggest surprise, Safari always selects the closest server correctly. Even if it goes offline for a while, after a few refreshes, it always finds the EU server again!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XrS1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XrS1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!XrS1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!XrS1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!XrS1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XrS1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png" width="444" height="264.17536534446765" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:958,&quot;resizeWidth&quot;:444,&quot;bytes&quot;:19889,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XrS1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!XrS1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!XrS1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!XrS1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa86d8b48-6660-4c76-b063-b10c73ec6fee_958x570.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>curl<br></h4><p>Curl also works correctly. First time it might not, but if you run the command twice, it always corrects to the nearest server.</p><p>If you have multiple VPSs around the world, try this command via ssh and see which one gets selected:</p><pre><code><code>curl https://rr-direct.hyperknot.com/server
test-us

curl https://rr-direct.hyperknot.com/server
test-eu</code></code></pre><h4>Cloudflare</h4><p>Cloudflare picks a random location based on your client IP and then sticks with it. (It behaves like client_ip_hash modulo server_num or similar.)</p><p>As you have seen in the images, the right-side rectangle is always green. On my home IP, no matter what I do, Cloudflare goes to the US server. Curl shows the same.</p><pre><code>curl https://rr-cf.hyperknot.com/server
test-us</code></pre><p>Now, if I go to my mobile hotspot, it always connects to the EU server.</p><p>If I log into some VPSes and run the same curl command, I can see this behavior across the world. Every VPS gets connected to a totally random location around the world, but always the same.</p><pre><code>curl https://rr-cf.hyperknot.com/server
test-sg</code></pre><p></p><h3>Client Behavior with Partially Offline Servers</h3><p>So what happens when one of the servers is offline? Say I stop the US server:</p><pre><code><code>service nginx stop</code></code></pre><h4>Chrome</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n3OL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n3OL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!n3OL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!n3OL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!n3OL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n3OL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png" width="338" height="201.10647181628391" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:958,&quot;resizeWidth&quot;:338,&quot;bytes&quot;:43370,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n3OL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!n3OL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!n3OL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!n3OL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4261f746-b85e-4407-bf6e-d01c5962e7bb_958x570.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h4>Firefox</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9GHE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9GHE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!9GHE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!9GHE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!9GHE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9GHE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png" width="330" height="196.34655532359082" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:958,&quot;resizeWidth&quot;:330,&quot;bytes&quot;:33146,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9GHE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!9GHE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!9GHE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!9GHE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb15577b7-7255-4c5f-bb86-0a66ed463bce_958x570.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h4>Safari</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ec5O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ec5O!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!ec5O!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!ec5O!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!ec5O!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ec5O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png" width="316" height="188.01670146137786" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:958,&quot;resizeWidth&quot;:316,&quot;bytes&quot;:41949,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ec5O!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png 424w, https://substackcdn.com/image/fetch/$s_!ec5O!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png 848w, https://substackcdn.com/image/fetch/$s_!ec5O!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png 1272w, https://substackcdn.com/image/fetch/$s_!ec5O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03015118-9864-4c4b-ab35-9e04b42b08f3_958x570.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h4>curl</h4><pre><code>curl https://rr-direct.hyperknot.com/server
test-eu</code></pre><p>As you can see, all clients correctly detect it and choose an alternative server.</p><p>Actually, they do this fallback so well that if I turn off the server while they are loading, they correct within &lt; 1 sec! Here is an animation of the 50x50 version of the same grid, on Safari:</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;c996aa19-8890-4c69-8759-83d386c4de46&quot;,&quot;duration&quot;:null}"></div><h4>Cloudflare</h4><p>And what about Cloudflare? As you can see in the screenshots above, Cloudflare does <strong>not</strong> detect an offline server. It keeps accessing the server it decided for your IP, regardless of whether it's online or offline.</p><p>If the server is offline, you are served offline. In curl, it returns:</p><pre><code>curl https://rr-cf.hyperknot.com/server
error code: 521</code></pre><p>I've been trying to understand what this behavior is, and I highly suspect it's a <strong>bug</strong> in their network. One reference I found in their&nbsp;<a href="https://developers.cloudflare.com/fundamentals/basic-tasks/protect-your-origin-server/#zero-downtime-failover">documentation</a>&nbsp;is this part:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!U7gF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!U7gF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png 424w, https://substackcdn.com/image/fetch/$s_!U7gF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png 848w, https://substackcdn.com/image/fetch/$s_!U7gF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png 1272w, https://substackcdn.com/image/fetch/$s_!U7gF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!U7gF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png" width="532" height="238.40345821325647" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:622,&quot;width&quot;:1388,&quot;resizeWidth&quot;:532,&quot;bytes&quot;:124868,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!U7gF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png 424w, https://substackcdn.com/image/fetch/$s_!U7gF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png 848w, https://substackcdn.com/image/fetch/$s_!U7gF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png 1272w, https://substackcdn.com/image/fetch/$s_!U7gF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86323993-bbaa-4d0b-b21c-72c2b44a2fcc_1388x622.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Based on this documentation - and by common sense as well - I believe Cloudflare should also behave like browsers and curl do.</p><p></p><h3>Cloudflare Wish List</h3><ol><li><p>At the very least, offline servers should be detected.</p></li><li><p>Moreover, it would also be really nice if the server with the lowest latency were selected, like in Safari!</p></li></ol><p>I mean, currently, if you have one server in the US and one in New Zealand, exactly 50% of your US users will be served from New Zealand, which makes no sense. Also, for Safari users, it's actually slower compared to not using Cloudflare!</p><p></p><div><hr></div><p>There is a <a href="https://news.ycombinator.com/item?id=41955912">HN discussion now</a>, where both the CEO and the CTO of Cloudflare replied!</p><p>Note 1: I've tried my best to understand articles&nbsp;<strong><a href="https://t.co/MefximeFqU">1</a></strong>,&nbsp;<strong><a href="https://t.co/IlYL4Emgz7">2</a></strong>,&nbsp;<strong><a href="https://t.co/GKE4mdUiNH">3</a></strong>&nbsp;which Matthew Prince&nbsp;<strong><a href="https://x.com/eastdakota/status/1850103009826554285">pointed out to me</a></strong>&nbsp;on X. As I understand, they are referring to Cloudflare servers as "servers", not users' servers behind A records. Also, I couldn't find anything related to Round Robin DNS.</p><p>Note 2: If you have any idea&nbsp;<strong>how I can keep running</strong>&nbsp;this experiment without paying for 3 VPS-es around the world, please comment below. I'd love to keep it running. Is there a serverless platform that supports HTTPS and Round Robin DNS?</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe to this blog</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[First month of OpenFreeMap]]></title><description><![CDATA[2k GitHub Stars, 300 req/sec, 2 TB per day]]></description><link>https://blog.hyperknot.com/p/first-month-of-openfreemap</link><guid isPermaLink="false">https://blog.hyperknot.com/p/first-month-of-openfreemap</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Thu, 24 Oct 2024 14:38:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3ps1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3ps1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png 424w, https://substackcdn.com/image/fetch/$s_!3ps1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png 848w, https://substackcdn.com/image/fetch/$s_!3ps1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png 1272w, https://substackcdn.com/image/fetch/$s_!3ps1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3ps1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png" width="200" height="233.4763948497854" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:544,&quot;width&quot;:466,&quot;resizeWidth&quot;:200,&quot;bytes&quot;:223293,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3ps1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png 424w, https://substackcdn.com/image/fetch/$s_!3ps1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png 848w, https://substackcdn.com/image/fetch/$s_!3ps1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png 1272w, https://substackcdn.com/image/fetch/$s_!3ps1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c79df1c-1966-49db-b65e-2a90dce5ae2e_466x544.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>I launched&nbsp;<a href="https://openfreemap.org/">OpenFreeMap</a>&nbsp;on&nbsp;<a href="https://news.ycombinator.com/item?id=41635592">HN</a>&nbsp;exactly a month ago. Well, it's not exactly correct, as I first submitted it to HN&nbsp;<a href="https://news.ycombinator.com/item?id=41593463">5 days before</a>, when absolutely nothing happened (1). The second time it became the&nbsp;<a href="https://bestofshowhn.com/2024">12th most successful</a>&nbsp;Show HN of 2024 (until today), with 848 points!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bWyg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bWyg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png 424w, https://substackcdn.com/image/fetch/$s_!bWyg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png 848w, https://substackcdn.com/image/fetch/$s_!bWyg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png 1272w, https://substackcdn.com/image/fetch/$s_!bWyg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bWyg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png" width="1438" height="396" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:396,&quot;width&quot;:1438,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:50924,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bWyg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png 424w, https://substackcdn.com/image/fetch/$s_!bWyg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png 848w, https://substackcdn.com/image/fetch/$s_!bWyg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png 1272w, https://substackcdn.com/image/fetch/$s_!bWyg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55767bc3-3c8c-4081-98d5-6aba2f23c8a8_1438x396.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>What did I change during those 5 days? I went on Reddit and launched it on&nbsp;<a href="https://www.reddit.com/r/selfhosted/comments/1fl8n8r/openfreemap_opensource_openstreetmap_vector_tile/">r/selfhosted</a>,&nbsp;<a href="https://www.reddit.com/r/opensource/comments/1fm6n4q/openfreemap_opensource_openstreetmap_vector_tile/">r/opensource</a>, and&nbsp;<a href="https://www.reddit.com/r/webdev/comments/1fnq7xg/openfreemap_opensource_map_hosting/">r/webdev</a>, each time iterating on the title and the description.</p><p>The great thing about Reddit was that it allowed me to interact with the community; some users even started a chat. It helped me realize what the important values of my project were - the self-hosting and open-source nature - while the free part isn't really special.</p><p>Which is strange, as the technically challenging part of this project is to offer free tile-hosting for public usage, but I guess developers are fed up with "free" projects - and I totally understand them.</p><p>Here are the before &amp; after titles of the two submissions.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T1rE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T1rE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png 424w, https://substackcdn.com/image/fetch/$s_!T1rE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png 848w, https://substackcdn.com/image/fetch/$s_!T1rE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png 1272w, https://substackcdn.com/image/fetch/$s_!T1rE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T1rE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png" width="1430" height="258" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:258,&quot;width&quot;:1430,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:68443,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T1rE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png 424w, https://substackcdn.com/image/fetch/$s_!T1rE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png 848w, https://substackcdn.com/image/fetch/$s_!T1rE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png 1272w, https://substackcdn.com/image/fetch/$s_!T1rE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2c600b6-7757-4fe0-a807-d0b8b27b3b1c_1430x258.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><h2>Reception</h2><p>I was worried about launching an open-source project, and I was especially worried about HN, a famous place where projects are torn to pieces and criticized harshly. To my biggest surprise, I got the total opposite on both Reddit and HN: very supportive and helpful comments!</p><p>Seriously, I was very humbled by how nice everyone was; I think it was one of the most positive Show HN threads I've read. The comments about the support plans/monetization were so on point that I decided to remove the whole section about support plans and simply choose GitHub Sponsors as the sole donation source.</p><p>On GitHub, the project got 2k stars in less than 2 weeks!</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eWzz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eWzz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png 424w, https://substackcdn.com/image/fetch/$s_!eWzz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png 848w, https://substackcdn.com/image/fetch/$s_!eWzz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png 1272w, https://substackcdn.com/image/fetch/$s_!eWzz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eWzz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png" width="220" height="91.14285714285714" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:174,&quot;width&quot;:420,&quot;resizeWidth&quot;:220,&quot;bytes&quot;:10504,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eWzz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png 424w, https://substackcdn.com/image/fetch/$s_!eWzz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png 848w, https://substackcdn.com/image/fetch/$s_!eWzz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png 1272w, https://substackcdn.com/image/fetch/$s_!eWzz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F10917cea-4281-4cea-a278-c4bde7cb5922_420x174.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>GitHub issues/discussions were about the following topics:</p><ul><li><p>Issues about bugs related to self-hosting and special setups - I believe I have fixed all of them by now. Thank you all for reporting them!</p></li><li><p>Questions which I thought were obvious, but it turns out they definitely are not. For example, the fact that the map on the homepage has scroll and rotation disabled doesn't mean that you would have it disabled on your website. I need to explain this more in the documentation.</p></li><li><p>And finally, there were some questions which were not directly related to OpenFreeMap, for example, transliteration issues in Planetiler.</p></li></ul><p>I also got the first successful reports of self-hosting working, and one user even pointed out an amazing&nbsp;<a href="https://contabo.com/en/storage-vps/">&#8364;4.5/month VPS</a>&nbsp;from Contabo which is perfectly capable of running this project. I'm super happy to hear that, as it might be a key element for the future of this project.</p><h2>Community contributions</h2><p><a href="https://x.com/CodingGarden">CJ</a>&nbsp;created a fantastic video on YouTube about this project. It's a great resource that contains a lot of information about the background of online maps and even has code examples in five different frameworks.</p><div id="youtube2-UAQogFwyna0" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;UAQogFwyna0&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/UAQogFwyna0?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2>Traffic</h2><p>In the last few days, traffic has started sky-rocketing. That's about 120 TB/month with the current speed on 2 servers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kGyM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kGyM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png 424w, https://substackcdn.com/image/fetch/$s_!kGyM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png 848w, https://substackcdn.com/image/fetch/$s_!kGyM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png 1272w, https://substackcdn.com/image/fetch/$s_!kGyM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kGyM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png" width="1204" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1204,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:199109,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kGyM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png 424w, https://substackcdn.com/image/fetch/$s_!kGyM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png 848w, https://substackcdn.com/image/fetch/$s_!kGyM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png 1272w, https://substackcdn.com/image/fetch/$s_!kGyM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65ae4c2a-218f-40fe-8a4d-42424f5f24ce_1204x832.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I looked into it and discovered that Sony Music&nbsp;<a href="https://www.chromakopia.com/">launched a project</a>&nbsp;using OpenFreeMap; almost all the traffic comes from this single website.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aK4C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aK4C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png 424w, https://substackcdn.com/image/fetch/$s_!aK4C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png 848w, https://substackcdn.com/image/fetch/$s_!aK4C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png 1272w, https://substackcdn.com/image/fetch/$s_!aK4C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aK4C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png" width="1456" height="1055" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1055,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:273153,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!aK4C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png 424w, https://substackcdn.com/image/fetch/$s_!aK4C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png 848w, https://substackcdn.com/image/fetch/$s_!aK4C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png 1272w, https://substackcdn.com/image/fetch/$s_!aK4C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8205847b-fa68-4a00-86c7-c3642615b666_1888x1368.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It's actually quite a nice website; I like it. Technically, it has no reason to load the full planet map. This could be just a 500 kB GeoJSON file, but the world isn't full of GIS experts who know how to make a simplified GeoJSON file with countries and US states merged. (Hint if you want to do this: go to&nbsp;<a href="https://geojson.xyz/">https://geojson.xyz/</a>)</p><p>The realistic alternative would have been for them to go with Mapbox or Maptiler.</p><p>So how much would this cost on those platforms?</p><p>This single website is making about 300 requests per second. That's about 777 million requests per month.</p><p>On Mapbox, it would be about 200 million "map loads." With a discount of $2 per 1,000 loads, it would be <strong>$400,000</strong> per month.</p><p>On Maptiler, it would be <strong>$300,000</strong> per month.</p><p>I'm actually really happy this works. If OpenFreeMap can serve $300,000 worth of map data on infrastructure which costs $175 per month, then I think it really has some value!</p><h2><strong>The Future and Financials</strong></h2><p>During this month, I have been thinking a lot about the future of this project, especially the financial part.</p><p>There are 3 parts:</p><ol><li><p>Infrastructure cost</p></li><li><p>Maintenance work</p></li><li><p>Improvements and new features</p></li></ol><h3><strong>The Server Cost</strong></h3><p>Currently, the server cost is about $175 per month, and the GitHub&nbsp;<strong><a href="https://github.com/sponsors/hyperknot">sponsors</a></strong>&nbsp;are at $105 per month. The first milestone would be to reach $175; then the project would cover the server cost! Please <a href="https://github.com/sponsors/hyperknot">sponsor</a> if you can!</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FggF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FggF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png 424w, https://substackcdn.com/image/fetch/$s_!FggF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png 848w, https://substackcdn.com/image/fetch/$s_!FggF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png 1272w, https://substackcdn.com/image/fetch/$s_!FggF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FggF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png" width="1418" height="230" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:230,&quot;width&quot;:1418,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25235,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FggF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png 424w, https://substackcdn.com/image/fetch/$s_!FggF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png 848w, https://substackcdn.com/image/fetch/$s_!FggF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png 1272w, https://substackcdn.com/image/fetch/$s_!FggF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa9a48ce4-e68c-4e56-bff5-8b1eaf64e956_1418x230.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This should be good for about 300 TB per month on Hetzner.</p><p>Of course, if Sony launches a few more projects on OpenFreeMap, then I will need to add more servers or figure out a way to limit the load. Some ideas:</p><ol><li><p>Make a really simple-to-follow self-hosting guide for Contabo VPS. Everyone can set up their local instance for 4.5 EUR per month.</p></li><li><p>Make a guide for proxying and adding a per-user CDN.</p></li><li><p>Reach out to Bunny or Cloudflare for sponsoring a CDN.</p></li><li><p>As a last resort, limit extreme load coming from a single website, like over 1 million requests per day. This really is a last resort.</p></li></ol><h3><strong>The Maintenance</strong></h3><p>The other part of the future is maintaining the project. This one has quite a black-and-white answer: I need to do this anyway. OpenFreeMap is the tile server for&nbsp;<a href="https://maphub.net/">MapHub</a>, and MapHub is my main income.</p><p>Basically, if I have to do it anyway, why not do it in the open?</p><p>Also, I'll remove the SLA part from the website. I want as good an SLA as possible; there is no point in differentiating and making two separate infrastructures, one with "free" load and one with "premium" load. The free service should have as good an SLA as possible.</p><h3>Improvements</h3><p>The third part of the future is improvements. For example, making new styles, fixing icons, etc. I believe this part can rightfully be connected to the financial success of the project. That is, priority #1 is to cover server costs, and if donations reach that, then I can invest time into improvements.</p><p>I'll work on the homepage to reflect these thoughts; I believe this direction could actually work.</p><p>If you have ideas about sponsorship, like which projects/foundations should I reach out to, please <a href="mailto:zsolt@hyperknot.com">contact me</a>.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe to this blog</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><p>(1) Well, not exactly true. <a href="https://x.com/kiwicopple">@kiwicopple</a>, the CEO of Supabase, noticed it and became my first GitHub Sponsor. Thank you!</p><p></p>]]></content:encoded></item><item><title><![CDATA[Is there now a generation of users who never worked with files?]]></title><description><![CDATA[MapHub's UI has remained largely consistent since I launched it eight years ago, with a prominent "Save" button visible in the top-right corner of the map.]]></description><link>https://blog.hyperknot.com/p/is-there-now-a-generation-of-users</link><guid isPermaLink="false">https://blog.hyperknot.com/p/is-there-now-a-generation-of-users</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Sat, 21 Sep 2024 09:00:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>MapHub's UI has remained largely consistent since I launched it eight years ago, with a prominent "Save" button visible in the top-right corner of the map. It turns orange when a save is needed.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D7jO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D7jO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png 424w, https://substackcdn.com/image/fetch/$s_!D7jO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png 848w, https://substackcdn.com/image/fetch/$s_!D7jO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png 1272w, https://substackcdn.com/image/fetch/$s_!D7jO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D7jO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png" width="410" height="161.9327731092437" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:376,&quot;width&quot;:952,&quot;resizeWidth&quot;:410,&quot;bytes&quot;:136289,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D7jO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png 424w, https://substackcdn.com/image/fetch/$s_!D7jO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png 848w, https://substackcdn.com/image/fetch/$s_!D7jO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png 1272w, https://substackcdn.com/image/fetch/$s_!D7jO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f59dad6-5f9e-498f-8319-b0a3bc4a8f49_952x376.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>For years, everyone understood they had to click the "Save" button to preserve their changes. However, recently, I've been receiving more and more support requests along the lines of: <br><em>"I lost all my work"</em> or <br><em>"I've been working on a map for days, and now I can't find it."</em></p><p>I explained to everyone that there's no need to worry; even if they accidentally edit or delete their maps, they can always recover previous versions or even their deleted maps by clicking on the "Version History" or "Restore Deleted Maps" buttons.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Eswx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Eswx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png 424w, https://substackcdn.com/image/fetch/$s_!Eswx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png 848w, https://substackcdn.com/image/fetch/$s_!Eswx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png 1272w, https://substackcdn.com/image/fetch/$s_!Eswx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Eswx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png" width="450" height="164.50471698113208" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:310,&quot;width&quot;:848,&quot;resizeWidth&quot;:450,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Eswx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png 424w, https://substackcdn.com/image/fetch/$s_!Eswx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png 848w, https://substackcdn.com/image/fetch/$s_!Eswx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png 1272w, https://substackcdn.com/image/fetch/$s_!Eswx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a8f0da9-545e-4cb5-9a8b-41ba6280c2c7_848x310.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>But more and more users were telling me they couldn't find anything. That's when I realized that many users today simply aren't used to saving files manually.</p><p>They've grown up using cloud-based editors like Google Docs, where autosave is the default. Of course, autosave is only possible if you have a robust, automatic history-tracking system built into your app, which Google Docs certainly has.</p><p>The thing is, you can only offer this feature if your app's architecture is designed from the ground up to support it. Since MapHub wasn't built that way, I had to come up with a solution to remind users that they need to save their work regularly.</p><p>I added a notice reminding users to save their maps. It appears three times for each new user and also when there was no save for 10 minutes.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Jroe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jroe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png 424w, https://substackcdn.com/image/fetch/$s_!Jroe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png 848w, https://substackcdn.com/image/fetch/$s_!Jroe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png 1272w, https://substackcdn.com/image/fetch/$s_!Jroe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jroe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png" width="432" height="179.81725888324874" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:328,&quot;width&quot;:788,&quot;resizeWidth&quot;:432,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Jroe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png 424w, https://substackcdn.com/image/fetch/$s_!Jroe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png 848w, https://substackcdn.com/image/fetch/$s_!Jroe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png 1272w, https://substackcdn.com/image/fetch/$s_!Jroe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb8ef48-8a16-4bad-b792-792b530ed8a2_788x328.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>This solution has worked wonderfully. It's one of those features where, after shipping it, we didn't hear anything more. The support requests stopped overnight, and no one is losing their work anymore.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">If you enjoyed this post, feel free to subscribe to this blog</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>You can also follow me on X <a href="https://x.com/hyperknot">@hyperknot</a> or bsky <a href="https://bsky.app/profile/hyperknot.com">@hyperknot.com</a><br></p><div><hr></div><p>Update, 1 Nov 2024:</p><p>This post appeared on <a href="https://news.ycombinator.com/item?id=41962608">HN</a>, I wrote the following <a href="https://news.ycombinator.com/item?id=42016231">comment</a>:</p><p>I'll try to collect my thoughts into one comment here about why there is no auto-save.</p><p>If you implement auto-save, users will expect every click/keystroke to be saved, like how Google Docs does it. Simply adding a 1-minute timer will make people lose work in the last minute, as they switch tabs, go offline, etc. and forget about it for days, when the browser clears tab state.</p><p>The other reason is that there is no Undo-Redo implemented on MapHub. Implementing Undo properly in a web app is not trivial if you haven't designed the whole app around a time-traveling state management. It's actually a really difficult problem to solve, even though it looks simple on the surface. Combining it with real-time collaboration is even more complex. Short story: there is no Undo-Redo.</p><p>So if you don't have Undo, then Save button plays the role of making a checkpoint, trying out something, reverting if needed. With autosave this could be ruined.</p><p>Also, you write that you expect every web app to auto-save, but this is still not the universal case today and definitely wasn't the case a few years ago. I agree that most VC-backed startups with hundred-million-dollar valuations have autosave in their web apps. Again, the proper solution is to have a time-traveling diff system implemented, which can easily get really complicated with real-time multi-user collaboration. Have a look at Figma's technical <a href="https://www.figma.com/blog/how-figmas-multiplayer-technology-works/">blog post</a> about this topic.</p><p>You might be right in saying that it's not a generation of users, but the same users being conditioned to web apps doing auto-save. I agree this is probably the case. The point of the article is this definitely wasn't the case all the time, and how I've experienced this on my side, during my 8+ years of running MapHub.</p><p><br></p>]]></content:encoded></item><item><title><![CDATA[Comparing Auth from Supabase, Firebase, Auth.js, Ory, Clerk and others]]></title><description><![CDATA[Looking at Auth providers from a software developer's perspective.]]></description><link>https://blog.hyperknot.com/p/comparing-auth-providers</link><guid isPermaLink="false">https://blog.hyperknot.com/p/comparing-auth-providers</guid><dc:creator><![CDATA[Zsolt Ero]]></dc:creator><pubDate>Thu, 16 Feb 2023 00:03:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4493a04-aa03-4863-92e4-6875f8db25fe_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>I&#8217;m Zsolt Ero. After reading blog posts all my life, but never writing one, I decided to start writing my thoughts while building. This is my first blog post.</em></p><p>I&#8217;m building a new web app and a browser extension. My previous app used server-side sessions with password login, but this time I wanted to support Single Sign-On (SSO), so I embarked on a journey to find an Auth solution.</p><p>My requirements are quite standard, or at least I thought they were:</p><ul><li><p>Never log a user out unless they want to.</p></li><li><p>Support Google / GitHub Single Sign-On (SSO).</p></li><li><p>Have affordable pricing for a freemium B2C app.</p></li><li><p>As an alternative for affordable pricing, have a nice self-hosting experience.</p><p></p></li></ul><p>I&#8217;ll be evaluating Auth providers from a software developer&#8217;s perspective. I&#8217;m not a security expert; I don&#8217;t have an opinion if a solution should use OAuth2 / OpenID Connect or something else. I&#8217;m looking for a setup that works reliably and gives a nice experience for my users.</p><blockquote><p>Note: There is a technical distinction between authentication (AuthN) and authorization (AuthZ). Since AuthZ is super simple in my use case, I&#8217;ll be evaluating the AuthN part.</p></blockquote><h2><strong>The good old setup</strong></h2><p>For <a href="https://maphub.net/">MapHub</a>, I&#8217;ve been using server-side sessions via Redis. No SSO, just password-based authentication. It&#8217;s been an extremely reliable and performant part of the infrastructure, running for almost 7 years now. Once set up, it&#8217;s been 100% stable and worry-free. </p><p>When I started writing this article, I logged into Plausible and saw that there were 19000 current visitors (Daily Mail just front-paged an <a href="https://www.dailymail.co.uk/femail/article-11674905/Interactive-Map-live-near-one-Britains-best-takeaways.html">article</a> featuring a MapHub embed).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cM4o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cM4o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png 424w, https://substackcdn.com/image/fetch/$s_!cM4o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png 848w, https://substackcdn.com/image/fetch/$s_!cM4o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png 1272w, https://substackcdn.com/image/fetch/$s_!cM4o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cM4o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png" width="222" height="46.676923076923075" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:82,&quot;width&quot;:390,&quot;resizeWidth&quot;:222,&quot;bytes&quot;:10836,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!cM4o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png 424w, https://substackcdn.com/image/fetch/$s_!cM4o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png 848w, https://substackcdn.com/image/fetch/$s_!cM4o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png 1272w, https://substackcdn.com/image/fetch/$s_!cM4o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ebea567-f7f0-4c20-9e37-8f70699deadc_390x82.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>While this traffic doesn&#8217;t happen every day; I found it amazing that the single server I&#8217;ve been using for years could handle it so smoothly.</p><p>Technically, the backend is based on &#8220;boring&#8221; technologies: Pyramid (17 yr), SQLAlchemy (16 yr), PostgreSQL (26 yr) and Redis (13 yr). I believe choosing boring technology for MapHub&#8217;s backend was one of the best choices I ever made.</p><blockquote><h4>How about performance? </h4><p>The #1 criticism about Python has always been how slow it is. The average response times during the Daily Mail Saturday evening hammer were 7-12 ms. Considering Google believes anything under 200 ms is good and 100 ms is excellent, I think these are really good numbers.</p><p>[1] curl -w &#8220;time_total&#8221; on localhost. It&#8217;s running on a dedicated AMD 3700X server.</p></blockquote><h2>The quest for a modern solution</h2><p>7 years have passed; I am building something new and aiming to improve in these aspects:</p><ul><li><p>No more mixing of templating between Python and JS: Write everything frontend related in React and make the backend JSON API only. </p></li><li><p>Support for Google / GitHub Single Sign-On (SSO).</p></li><li><p>Support for running serverless functions. Just a few endpoints for long-running functions.</p></li><li><p>And most importantly, rule #1: <strong>Do not roll my own auth.</strong> I&#8217;m looking for a stable and trusted solution made by experts in the field.</p></li></ul><p>For the React + JSON API I decided to go with Next.js, but I&#8217;m trying to keep the Next.js backend part as &#8220;lite&#8221; as possible and keep using Python + SQLAlchemy for the API. (Once you&#8217;ve invested enough time to enjoy using SQLAlchemy, you don&#8217;t want to migrate to anything else.)</p><blockquote><p>How did I choose which Auth solution to try out? I&#8217;ve read a lot of Hacker News and Reddit comments and tried them out in the order presented here. For some, I&#8217;ve invested 1 week+ of my time, for others, just a few hours.</p></blockquote><div><hr></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!J49V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!J49V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png 424w, https://substackcdn.com/image/fetch/$s_!J49V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png 848w, https://substackcdn.com/image/fetch/$s_!J49V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png 1272w, https://substackcdn.com/image/fetch/$s_!J49V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!J49V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png" width="380" height="118.75" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:220,&quot;width&quot;:704,&quot;resizeWidth&quot;:380,&quot;bytes&quot;:57134,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!J49V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png 424w, https://substackcdn.com/image/fetch/$s_!J49V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png 848w, https://substackcdn.com/image/fetch/$s_!J49V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png 1272w, https://substackcdn.com/image/fetch/$s_!J49V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7a75673-46c4-4133-916d-a6971e32ac2f_704x220.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>Supabase</h2><p><a href="https://supabase.com/">Supabase</a> is the largest startup in this article, having received over $110 million in funding. They are making a full platform &#8220;open source Firebase alternative&#8221;, and if that&#8217;s not enough, it&#8217;s all based on PostgreSQL.</p><p>They offer amazing value: you get a managed PostgreSQL + the whole platform for $25 per month. This also includes auth for up to 100,000 monthly users, which would be hundreds or even thousands of dollars on other auth platforms.</p><p><strong>Supabase Auth</strong> is the gateway drug to the platform. In theory, you can just use Auth, but the magic is in the interconnectedness between their systems. For example, this function inserts a new user into your tables when a user registers on Supabase Auth.</p><pre><code><code>create function public.handle_new_user()
returns trigger as $$
begin
  insert into public.profiles (id, full_name, avatar_url)
  values (new.id, new.raw_user_meta_data-&gt;&gt;'full_name', new.raw_user_meta_data-&gt;&gt;'avatar_url');
  return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();</code></code></pre><p>Once you&#8217;ve started using this, you&#8217;ll never leave. It solves the number one problem with auth systems, which is how to synchronize the users of the auth system with the users of your backend system. It also creates the ultimate vendor lock-in. Luckily it&#8217;s an open-source platform, so you can always go self-hosted if you want to.</p><p></p><h4>Is Supabase solid?</h4><p>For <strong>Auth</strong>, unfortunately, no. I&#8217;ve been constantly getting logged out randomly from my own app, so I decided to look into how they handle the auth in detail. I quickly found out it was not an isolated case: There are many reports on GitHub about other users experiencing random logouts.</p><p></p><h4>Red flag 1: No setting for session lifetime</h4><p>First, there is no option to set the session lifetime. This is a very important setting on every other platform with detailed documentation. For Supabase, there is no mention of it in the docs and no setting on the UI.</p><p>This is probably the most important parameter for any auth solution and is it completely missing here?</p><p>There is a single setting called &#8220;JWT expiry limit&#8221;, which confuses users, as people are setting it to the maximum value of one week, thinking it means session lifetime. In reality, it is only setting the access token&#8217;s expiry time: a limit as short as 10 seconds should still give an OK user experience, without anyone experiencing logouts.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uN_8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uN_8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png 424w, https://substackcdn.com/image/fetch/$s_!uN_8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png 848w, https://substackcdn.com/image/fetch/$s_!uN_8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png 1272w, https://substackcdn.com/image/fetch/$s_!uN_8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uN_8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png" width="1456" height="257" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c1ab5194-baa6-4353-afe4-24408c097994_1690x298.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:257,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image&quot;,&quot;title&quot;:&quot;image&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image" title="image" srcset="https://substackcdn.com/image/fetch/$s_!uN_8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png 424w, https://substackcdn.com/image/fetch/$s_!uN_8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png 848w, https://substackcdn.com/image/fetch/$s_!uN_8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png 1272w, https://substackcdn.com/image/fetch/$s_!uN_8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1ab5194-baa6-4353-afe4-24408c097994_1690x298.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><h4>Red flag 2: Client-side unencrypted tokens</h4><p>Every information is stored client-side. This means either non-HttpOnly cookies or localStorage. The content is not encrypted, so every script that runs on your website has access to your users&#8217; access_token, refresh_token, provider_token and provider_refresh_token in clear text.</p><p>Now, I&#8217;m not an auth expert, so I cannot evaluate how bad this behavior is, but every other solution explicitly mentions why they are not doing this.</p><p></p><h4>Red flag 3: Inconsistent, undocumented behavior, no communication</h4><p>Some of the official <a href="https://github.com/supabase/supabase/tree/master/examples/user-management">examples</a> (for example React) use the <code>supabase-js</code> package, which stores data in localStorage, while others (for example Next.js) use the <code>auth-helpers</code> package, which stores data in a client-side cookie. None of this is documented anywhere.</p><p>The most important information I&#8217;m trying to figure out is what happens to the auth.sessions / refresh_tokens tables on the server.</p><ul><li><p>If these are cleaned up at regular intervals, when exactly and how can we control this? This would be the missing session lifetime setting mentioned above.</p></li><li><p>If these are not cleaned up then how do people use Supabase in production? Do they really keep all those sessions / tokens forever?</p></li></ul><p>I wrote on their Discord but received no answer. I kept writing my findings in a lonely thread on their <a href="https://github.com/supabase/supabase/discussions/11100">GitHub Discussions</a>, receiving no response for 1.5 months. I opened an <a href="https://github.com/supabase/gotrue/issues/886">issue</a> directly on the auth repo, which finally received a response after a month from a dev. The official answer is that I shouldn&#8217;t worry and that &#8220;random logouts should not be happening&#8221;. Unfortunately, they do happen, which is the reason I looked into the implementation.</p><p></p><h4>Red flag 4: Lack of care for Auth</h4><p>When it comes to shipping new features, Supabase is one of the most impressive companies I&#8217;ve seen. Simply reading their newsletter can be overwhelming: they ship so many features so rapidly.</p><p>At the same time, I feel there is a lack of care for one of their core packages: Auth. For example, using their Next.js middleware results in a user logout. I&#8217;m not talking about a very exotic setup, this can be <a href="https://github.com/supabase/auth-helpers/issues/414">reproduced</a> on their official example. However, apart from a few users trying to guess what&#8217;s going on, no one seems to care.</p><p></p><h4>Red flag 100: No 2FA on their own platform</h4><p>I honestly couldn&#8217;t believe it, I just thought I couldn&#8217;t find the setting. I had to ask for confirmation about it on Supabase Discord. </p><p>There is no 2FA available for app.supabase.com! </p><p>The platform, which you are supposed to trust with your business data, your customers&#8217; private information, and your payment processor&#8217;s API keys. The platform, which received over $110 million in funding and ships a new feature every week. They don&#8217;t have 2FA in 2023.</p><blockquote><p>Note: It probably also tells a lot about Supabase Auth, which offers 2FA and is used for their platform. If they are not trusting their own solution&#8217;s 2FA, then why is it even offered?</p></blockquote><p></p><h4>Conclusion</h4><p>I came for the Auth and wanted to stay for the platform. They offer tremendous value for $25. I really wanted to like it, I&#8217;ve spent way more time trying to make it work, compared to any other solution.</p><p>Unfortunately, there are way too many red flags for me about Supabase Auth, so I decided to look for alternatives.</p><p>I understand that their Auth platform is a fork of Netlify&#8217;s gotrue and they put a lot of effort into making it work, but the end result is still not something I&#8217;d want to lock into. Now that Supabase is a big, well-funded company with some of the best developers, they could probably develop a much better auth platform from scratch. I hope they&#8217;ll do it and become an amazing platform with a solid Auth.</p><blockquote><p>Note, I&#8217;m really puzzled about how the Hacker News community universally endorses Supabase. HN is known to be very critical when it comes to discussing small to big projects, even small blog posts are scrutinized, yet they give an almost universal approval for Supabase. It was the reason I picked it first and I was the most surprised when I found the above-mentioned red flags.</p></blockquote><div><hr></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3Try!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3Try!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png 424w, https://substackcdn.com/image/fetch/$s_!3Try!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png 848w, https://substackcdn.com/image/fetch/$s_!3Try!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png 1272w, https://substackcdn.com/image/fetch/$s_!3Try!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3Try!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png" width="394" height="145.39797395079594" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:510,&quot;width&quot;:1382,&quot;resizeWidth&quot;:394,&quot;bytes&quot;:240190,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!3Try!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png 424w, https://substackcdn.com/image/fetch/$s_!3Try!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png 848w, https://substackcdn.com/image/fetch/$s_!3Try!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png 1272w, https://substackcdn.com/image/fetch/$s_!3Try!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a768e46-79c5-4ba7-afc4-a1ff03b8eb8d_1382x510.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>NextAuth.js / Auth.js</h2><p>NextAuth.js is a very popular choice these days, advertising a smooth developer experience with Next.js; however, I have still decided not to go with it.</p><p>The reasons are most evident on the GitHub <a href="https://github.com/nextauthjs/next-auth/graphs/contributors">Contributors graph</a>, where I can see that:</p><ul><li><p>It&#8217;s a project that the original developer abandoned 2 years ago.</p></li><li><p>Another developer has picked it up and is actively working on it, doing 90% of the effort today.</p></li><li><p>The current developer&#8217;s <a href="https://github.com/balazsorban44?tab=repositories&amp;q=&amp;type=&amp;language=&amp;sort=stargazers">background</a> seems to be React and Next projects. Nothing security- or backend-related.</p></li></ul><p>The other reason is that it&#8217;s not clear what they really offer. You can use a database or not. You can wrap other providers or not. You can use sessions or use JWT + JWS / JWE / JWK.</p><p>In comparison, the other solutions are full companies with a proven track record in security and they offer 1/10 of what NextAuth.js offers, developed by a single person.</p><p>I understand this is not a friendly or optimistic opinion, but choosing an Auth solution is not the same as selecting a date picker library, which you can replace in an afternoon.</p><p>I&#8217;m looking for a battle-tested auth solution developed and maintained by people who have a strong background in security. NextAuth.js didn&#8217;t pass this test for me.</p><div><hr></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!55o1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!55o1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png 424w, https://substackcdn.com/image/fetch/$s_!55o1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png 848w, https://substackcdn.com/image/fetch/$s_!55o1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png 1272w, https://substackcdn.com/image/fetch/$s_!55o1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!55o1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png" width="266" height="100.94358974358974" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:148,&quot;width&quot;:390,&quot;resizeWidth&quot;:266,&quot;bytes&quot;:8331,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!55o1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png 424w, https://substackcdn.com/image/fetch/$s_!55o1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png 848w, https://substackcdn.com/image/fetch/$s_!55o1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png 1272w, https://substackcdn.com/image/fetch/$s_!55o1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd660c50d-ad23-46f6-8a04-3a5c99a08235_390x148.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>Clerk</h2><p><a href="https://clerk.dev/">Clerk</a> is a polished solution by a company that is 100% focused on auth. They have a solid financial background ($25 million in funding). Their website is functional and beautiful, as is their documentation.</p><p>Have a look at configuring session lifetime below: it shows exactly what&#8217;s important. A short description in the dashboard, a detailed description in the <a href="https://clerk.dev/docs/authentication/session-options#session-lifetime">docs</a>. Session lifetime can be set to 10 years, just what I was looking for!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BXX3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BXX3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png 424w, https://substackcdn.com/image/fetch/$s_!BXX3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png 848w, https://substackcdn.com/image/fetch/$s_!BXX3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png 1272w, https://substackcdn.com/image/fetch/$s_!BXX3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BXX3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png" width="1456" height="808" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:808,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:476205,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!BXX3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png 424w, https://substackcdn.com/image/fetch/$s_!BXX3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png 848w, https://substackcdn.com/image/fetch/$s_!BXX3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png 1272w, https://substackcdn.com/image/fetch/$s_!BXX3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42cf736d-808c-4059-9a6f-a59410f44954_1672x928.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>They also have a super clean integration with Next.js.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xNwm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xNwm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png 424w, https://substackcdn.com/image/fetch/$s_!xNwm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png 848w, https://substackcdn.com/image/fetch/$s_!xNwm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png 1272w, https://substackcdn.com/image/fetch/$s_!xNwm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xNwm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png" width="480" height="245.75342465753425" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:598,&quot;width&quot;:1168,&quot;resizeWidth&quot;:480,&quot;bytes&quot;:299089,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xNwm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png 424w, https://substackcdn.com/image/fetch/$s_!xNwm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png 848w, https://substackcdn.com/image/fetch/$s_!xNwm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png 1272w, https://substackcdn.com/image/fetch/$s_!xNwm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2bdbfb47-cfe7-4af1-81bf-f8182b5cd02f_1168x598.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Pricing and conclusion</h4><p>For 10,000 active monthly users, Clerk costs $550 in the Business plan.</p><ul><li><p>If you only have paying users, and they pay you at least $5 a month, this would be max 1% of your revenue. I&#8217;d gladly pay 1% for a polished auth solution.</p></li><li><p>On the other hand, if your business model is freemium, when only 1-2% of your users are on a paid plan, this could be 50% of your revenue. In this case, it&#8217;s clearly cost prohibitive.</p></li></ul><p>In my opinion, Clerk&#8217;s Business plan is the nicest hosted auth solution if your business model fits their pricing. In my case it didn&#8217;t, so I continued my journey.</p><div><hr></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3Dfr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3Dfr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png 424w, https://substackcdn.com/image/fetch/$s_!3Dfr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png 848w, https://substackcdn.com/image/fetch/$s_!3Dfr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png 1272w, https://substackcdn.com/image/fetch/$s_!3Dfr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3Dfr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png" width="312" height="85.91304347826087" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:114,&quot;width&quot;:414,&quot;resizeWidth&quot;:312,&quot;bytes&quot;:10112,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!3Dfr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png 424w, https://substackcdn.com/image/fetch/$s_!3Dfr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png 848w, https://substackcdn.com/image/fetch/$s_!3Dfr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png 1272w, https://substackcdn.com/image/fetch/$s_!3Dfr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F430772c6-dc28-4026-9b7b-da742ce33b3a_414x114.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>FusionAuth</h2><p><a href="https://fusionauth.io/">FusionAuth</a> is a company specializing in Auth, targeting bigger companies and Enterprises. They offer a self-hostable version of their software for free. It is not open-source, but you are allowed to run the binaries after accepting their license. </p><p>There is a Docker Compose version offered, so hosting it should be quite simple.</p><p>Once you start it, you get into a maze of settings. It is truly a maze. Just inside the &#8220;Edit Application&#8221; dialog, I&#8217;ve counted over 70 fields.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0_4G!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0_4G!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png 424w, https://substackcdn.com/image/fetch/$s_!0_4G!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png 848w, https://substackcdn.com/image/fetch/$s_!0_4G!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png 1272w, https://substackcdn.com/image/fetch/$s_!0_4G!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0_4G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png" width="1230" height="932" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:932,&quot;width&quot;:1230,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:158275,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0_4G!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png 424w, https://substackcdn.com/image/fetch/$s_!0_4G!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png 848w, https://substackcdn.com/image/fetch/$s_!0_4G!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png 1272w, https://substackcdn.com/image/fetch/$s_!0_4G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb308f29-a4ba-4fff-bbff-25be2198a334_1230x932.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>What I found great about FusionAuth is that they support both a login screen inside the app, as well as external login pages. Since I&#8217;m planning to develop a browser extension, I&#8217;d really prefer to have a custom-styled login screen inside the app, without pushing the users to a different subdomain first.</p><p>Having said that, I found absolutely no resources for building out this interface in React, nor for integrating their API in Next.js.</p><p>All in all, FusionAuth is probably a workable solution, but it would require investing way more time compared to alternatives. In summary, I would be spending a lot of time on the wrong priorities just to be able to use a closed-source software. I prefer to look for alternatives.</p><div><hr></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!reat!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!reat!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png 424w, https://substackcdn.com/image/fetch/$s_!reat!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png 848w, https://substackcdn.com/image/fetch/$s_!reat!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png 1272w, https://substackcdn.com/image/fetch/$s_!reat!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!reat!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png" width="312" height="107.35714285714286" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/caf3b798-33a9-4211-b143-493df7035580_2108x726.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:501,&quot;width&quot;:1456,&quot;resizeWidth&quot;:312,&quot;bytes&quot;:395258,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!reat!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png 424w, https://substackcdn.com/image/fetch/$s_!reat!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png 848w, https://substackcdn.com/image/fetch/$s_!reat!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png 1272w, https://substackcdn.com/image/fetch/$s_!reat!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcaf3b798-33a9-4211-b143-493df7035580_2108x726.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>ZITADEL</h2><p><a href="https://zitadel.com/">ZITADEL</a> is a Swiss company, just a drop from Munich-based Ory. Both of these companies seem to have a background in serving European government and Enterprise clients. Great news when it comes to security - probably these solutions are as battle tested as it gets.</p><p>On the other hand, it might not be such great news when it comes to setting up a simple Auth solution for a web app. Let&#8217;s see how ZITADEL scores.</p><h4>Self-hosting experience</h4><p>I have to say, without exception, their self-hosting experience is as smooth as it gets. First, they open-sourced their full solution, 1:1 identical to their hosted offering. This means the full backend and frontend, not just core components plus long evenings of tweaking config files.</p><p>Second, the hosting is so simple that it&#8217;s basically a single Docker container. You start a single container and you get a 1:1 identical offering to what you&#8217;d get in their Cloud offering.</p><blockquote><p>There is an interesting <a href="https://github.com/zitadel/zitadel/discussions/4175">issue</a> on GitHub where the founder of ZITADEL and Ory are discussing their products&#8217; differences. One key topic seems to be the self-hosting experience. In my finding, they couldn&#8217;t be further - to the advantage of ZITADEL.</p></blockquote><h4>The maze</h4><p>Once it&#8217;s up and running, you find yourself in a smooth UI that contains hundreds if not thousands of settings. You have:</p><ul><li><p>Organizations</p></li><li><p>Project</p></li><li><p>Applications</p></li><li><p>Roles</p></li><li><p>Grants</p></li><li><p>Authorizations</p></li><li><p>Users</p></li><li><p>Identity providers</p></li><li><p>Memberships</p></li><li><p>Actions</p></li><li><p>Flows</p></li><li><p>Domains</p></li><li><p>Instances</p></li></ul><p>I&#8217;ve spent a few hours with it and I couldn&#8217;t figure out how to make a simple login screen that looks like the one on their landing page:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HEnr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HEnr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png 424w, https://substackcdn.com/image/fetch/$s_!HEnr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png 848w, https://substackcdn.com/image/fetch/$s_!HEnr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png 1272w, https://substackcdn.com/image/fetch/$s_!HEnr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HEnr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png" width="230" height="439.30795847750863" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1104,&quot;width&quot;:578,&quot;resizeWidth&quot;:230,&quot;bytes&quot;:371033,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!HEnr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png 424w, https://substackcdn.com/image/fetch/$s_!HEnr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png 848w, https://substackcdn.com/image/fetch/$s_!HEnr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png 1272w, https://substackcdn.com/image/fetch/$s_!HEnr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da4b224-0888-4c31-9385-6078ddd50af0_578x1104.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Setting up Single Sign-On for example looks like this. Here, I had to figure out Google&#8217;s issuer is &#8220;https://accounts.google.com&#8221; and fill in every value myself:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NVFv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NVFv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png 424w, https://substackcdn.com/image/fetch/$s_!NVFv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png 848w, https://substackcdn.com/image/fetch/$s_!NVFv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png 1272w, https://substackcdn.com/image/fetch/$s_!NVFv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NVFv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png" width="296" height="508.4785553047404" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1522,&quot;width&quot;:886,&quot;resizeWidth&quot;:296,&quot;bytes&quot;:354302,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!NVFv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png 424w, https://substackcdn.com/image/fetch/$s_!NVFv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png 848w, https://substackcdn.com/image/fetch/$s_!NVFv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png 1272w, https://substackcdn.com/image/fetch/$s_!NVFv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57c9a831-662b-4fe1-bafb-4744ff6b0353_886x1522.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here is how the same screen looks in Clerk, for example:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Nyuy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nyuy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png 424w, https://substackcdn.com/image/fetch/$s_!Nyuy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png 848w, https://substackcdn.com/image/fetch/$s_!Nyuy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png 1272w, https://substackcdn.com/image/fetch/$s_!Nyuy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nyuy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png" width="464" height="507.97802197802196" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1594,&quot;width&quot;:1456,&quot;resizeWidth&quot;:464,&quot;bytes&quot;:779395,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Nyuy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png 424w, https://substackcdn.com/image/fetch/$s_!Nyuy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png 848w, https://substackcdn.com/image/fetch/$s_!Nyuy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png 1272w, https://substackcdn.com/image/fetch/$s_!Nyuy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f040e9b-f635-49ee-8d67-9f075091dca2_1474x1614.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A few clicks vs. hours of debugging how to add each of those providers, one by one.</p><h4>Login screen</h4><p>ZITADEL only offers sign-up/login on an external login screen, i.e. your users will be redirected to auth.company.com, where they&#8217;ll see a page hosted by ZITADEL and they&#8217;ll be redirected back to your app after logging in. The limitation of this, of course, is that the user leaves your website for an external one that has no menubar, different design, etc., and is then redirected back. </p><p>Not a huge limitation, but I prefer to have React components and implement it inside my app, especially if flows like changing password or email need to happen on the same UI.</p><h4>Next.js support</h4><p>ZITADEL is one of the few solutions which doesn&#8217;t provide a Next.js library. They have an example that uses NextAuth.js where there is a &#8220;provider&#8221; for ZITADEL, but then you&#8217;ve introduced a dependency both on NextAuth.js and on ZITADEL. Twice the maintenance of keeping them updated, as well as twice the attack surface.</p><p>Case in point: simply logging in with an email &amp; password in their example app results in 5 cookies and 1 localStorage key.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mT67!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mT67!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png 424w, https://substackcdn.com/image/fetch/$s_!mT67!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png 848w, https://substackcdn.com/image/fetch/$s_!mT67!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png 1272w, https://substackcdn.com/image/fetch/$s_!mT67!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mT67!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png" width="592" height="117.6223316912972" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:242,&quot;width&quot;:1218,&quot;resizeWidth&quot;:592,&quot;bytes&quot;:88661,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mT67!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png 424w, https://substackcdn.com/image/fetch/$s_!mT67!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png 848w, https://substackcdn.com/image/fetch/$s_!mT67!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png 1272w, https://substackcdn.com/image/fetch/$s_!mT67!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b8953cc-f20a-4f9b-a659-56751a7f9322_1218x242.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>I&#8217;m not looking forward to debugging random logouts on this. It was hard enough with a single cookie on Supabase.</p><p></p><h4>Conclusion</h4><p>The architecture of ZITADEL is probably solid, and with enough time spent, I could probably figure out all the configuration issues. Their company was responsive, they always replied immediately on GitHub in a helpful and professional way.</p><p>If they could add a native Next.js library as well as a detailed tutorial about how to get from zero to the clean login UI like they are advertising, it could even be a winner!</p><p>For now, I decided to use different solutions.</p><div><hr></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GdSL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GdSL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png 424w, https://substackcdn.com/image/fetch/$s_!GdSL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png 848w, https://substackcdn.com/image/fetch/$s_!GdSL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png 1272w, https://substackcdn.com/image/fetch/$s_!GdSL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GdSL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png" width="200" height="86.41975308641975" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:140,&quot;width&quot;:324,&quot;resizeWidth&quot;:200,&quot;bytes&quot;:24106,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GdSL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png 424w, https://substackcdn.com/image/fetch/$s_!GdSL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png 848w, https://substackcdn.com/image/fetch/$s_!GdSL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png 1272w, https://substackcdn.com/image/fetch/$s_!GdSL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F024f390d-83bb-4a8e-8b1f-79b39df1c276_324x140.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>Firebase</h2><p><a href="https://firebase.google.com/">Firebase</a> needs no introduction, it&#8217;s been the #1 solution for &#8220;backend-as-a-service&#8221; platforms for 11 years now. It was founded in 2012, and acquired by Google in 2014 and they have been offering its services at very affordable prices ever since. Their name is so strong that Supabase&#8217;s title on their homepage is simply &#8220;open source Firebase alternative&#8221;.</p><p>Online I&#8217;ve seen most people criticizing their Functions product, but Auth seems to be a very solid solution that is polished by now. </p><h4>Client-side magic</h4><p>Firebase Auth seems to be the only solution I found that offers the whole auth experience client side. It really is magical: you call a single function and auth is set up and running, including UI. You don&#8217;t have to know or understand anything about Auth or backends to make it work.</p><h4>Abandoned libraries</h4><p>Having said that, their React lib is abandoned and is broken on React 18. Right now, the way to use it today is by browsing GitHub issues where people are trying to figure out how to make it work. One person wrote a <a href="https://github.com/firebase/firebaseui-web-react/pull/173#issuecomment-1151532176">snippet</a> for React and <a href="https://github.com/firebase/firebaseui-web-react/pull/173#issuecomment-1215648239">another one</a> for Next.js, which received dozens of upvotes. You copy-paste those into your code and hope it keeps working - not exactly the developer experience you&#8217;d expect from a solid platform.</p><p>Also, I cannot get over the require() inside useEffect:</p><pre><code>useEffect(() =&gt; {
        // Firebase UI only works on the Client. So we're loading the package only after
        // the component has mounted, so that this works when doing server-side rendering.
        setFirebaseui(require('firebaseui'));  // &lt;----- this
    }, []);</code></pre><h4>Free forever - or is it?</h4><p>One of the best things about Firebase Auth is that it&#8217;s completely free for unlimited users. Probably they are the only provider which offers totally free Auth, no matter how big your project grows.</p><p>Now, if we look into the details, you can see that it&#8217;s a bit more complicated. Basically, they offer two systems, the original one &#8220;Firebase Auth&#8221; which is free, and a new one called &#8220;Firebase Auth with Identity platform&#8221;, which offers more features like MFA, Blocking functions and SAML.</p><p>Now, if you want to support a single customer needing some of this, you&#8217;d need to migrate all your users over to the new system. At which point it's going to be as expensive as other specialist auth providers.</p><h4>The writing on the wall</h4><p>The original Auth solution is being <a href="https://cloud.google.com/identity-platform/docs/product-comparison">renamed</a> in more and more places to &#8220;Firebase Authentication <strong>Legacy</strong>&#8221;. Now, if you open <a href="https://killedbygoogle.com/">Killed By Google</a> it doesn&#8217;t exactly give a reassuring feeling for a Google product that is already called Legacy.</p><p>I guess the legacy solution will be shut down at one point and the new &#8220;Identity platform&#8221; will become the only Firebase Auth offering. There is nothing wrong with that, but we shouldn&#8217;t think of Firebase Auth anymore as a free offering, but as a paid offering with a generous free tier (50k users!).</p><h4>How do you sync user data?</h4><p>Technically the biggest challenge with using Firebase Auth is how to sync your user data with your backend. </p><p>The #1 Stack Overflow <a href="https://stackoverflow.com/a/70171351/518169">answer</a> for this question is basically &#8220;The easiest way is actually to <em>not</em> synchronize auth data&#8221;. Now, this might be just a single answer but catches the core idea: Firebase is really designed around the idea that you embrace Firebase as a platform, you use their DB offerings, their Functions, everything. They really don&#8217;t want you to use your own backend server with PostgreSQL and try to sync user data between the two systems.</p><p>You can find other answers which involve using Functions that trigger on Auth events, but making a reliable system based on this is not a simple task. It&#8217;d probably involve some real-time functions + a retry queue for failed events + overnight full export from Firebase with some clever diffing upon importing it.</p><h4>Conclusion</h4><p>Even with all the limitations, Firebase is still one of the best choices today when it comes to Auth. The abandoned React library doesn&#8217;t give a good feeling but the linked GitHub snippets work and you can get the first integration done super quickly.</p><p>Later on, it might give you headaches if you want to sync user data to your own DB, but if you are happy to use their DB it can be a solid choice.</p><p>Their free offering will probably be shut down, but their paid offering has a very generous free tier, which should cover most projects.</p><div><hr></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!F24n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!F24n!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png 424w, https://substackcdn.com/image/fetch/$s_!F24n!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png 848w, https://substackcdn.com/image/fetch/$s_!F24n!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png 1272w, https://substackcdn.com/image/fetch/$s_!F24n!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!F24n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png" width="304" height="86.85714285714286" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/137450e3-5d1f-462b-b92b-fde74496c320_616x176.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:176,&quot;width&quot;:616,&quot;resizeWidth&quot;:304,&quot;bytes&quot;:13799,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!F24n!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png 424w, https://substackcdn.com/image/fetch/$s_!F24n!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png 848w, https://substackcdn.com/image/fetch/$s_!F24n!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png 1272w, https://substackcdn.com/image/fetch/$s_!F24n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137450e3-5d1f-462b-b92b-fde74496c320_616x176.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>Supertokens</h2><p><a href="https://supertokens.com/">Supertokens</a> is a relatively new startup offering hosted Auth solutions with an open-source codebase. Their self-hosting experience is really nice, there is almost nothing to configure, no web UI, just a few values. From all the solutions listed here, it might have been the simplest to get up and running. </p><p>The actual configuration happens inside your app, which seems to be a very unique solution. Here is for example the <a href="https://github.com/supertokens/next.js/tree/canary/examples/with-supertokens/config">config folder</a> of their Next.js example app.</p><h4>React first</h4><p>The interesting thing about Supertokens is that they especially target React developers. Their <a href="https://github.com/supertokens/supertokens-core">core repo</a> has 660 commits, while their <a href="https://github.com/supertokens/supertokens-node">Node</a> + <a href="https://github.com/supertokens/supertokens-auth-react">React</a> repos have almost 2000 commits together.</p><p>It has both a good and a bad side. The good side is that getting it up and running in a React codebase is literally a few clicks. They even offer their own &#8220;create-supertokens-app&#8221;, which is an interesting idea but I&#8217;d only use it to create an example app.</p><h4>Implementation details all over the codebase</h4><p>The bad side is that everything is super hard-wired into their way of handling React state management, which really doesn&#8217;t go well if you are using a different state management solution.</p><p>Also, there are implementation details all over your app code. For example in their <a href="https://github.com/supertokens/next.js/tree/canary/examples/with-supertokens/pages">official example</a>, all the following is used in pages/:</p><ul><li><p>SuperTokensReact</p></li><li><p>supertokensNode</p></li><li><p>SuperTokensWrapper</p></li><li><p>superTokensNextWrapper</p></li><li><p>Session.attemptRefreshingSession</p></li><li><p>Session.getSession</p></li><li><p>verifySession</p></li><li><p>redirectToAuth</p></li><li><p>ThirdPartyEmailPassword.signOut</p></li><li><p>pageProps.fromSupertokens === 'needs-refresh'</p></li><li><p>err.type === Session.Error.TRY_REFRESH_TOKEN</p></li><li><p>err.type === Session.Error.UNAUTHORISED</p></li><li><p>SessionAuth</p></li><li><p>useSessionContext</p></li><li><p>SuperTokens.canHandleRoute</p></li><li><p>session.getAccessTokenPayload</p></li><li><p>supertokens-node/framework/express middleware</p></li></ul><p>Also, once logged in with a simple password auth, you get 5 cookies. As I said, I&#8217;m not a security expert, but 5 cookies just feel a hint too much for me.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XBLw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XBLw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png 424w, https://substackcdn.com/image/fetch/$s_!XBLw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png 848w, https://substackcdn.com/image/fetch/$s_!XBLw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png 1272w, https://substackcdn.com/image/fetch/$s_!XBLw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XBLw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png" width="488" height="134.9787234042553" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/beb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:260,&quot;width&quot;:940,&quot;resizeWidth&quot;:488,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XBLw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png 424w, https://substackcdn.com/image/fetch/$s_!XBLw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png 848w, https://substackcdn.com/image/fetch/$s_!XBLw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png 1272w, https://substackcdn.com/image/fetch/$s_!XBLw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbeb6fbf1-0ea6-4db4-accf-e467560686e7_940x260.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h4>430 kB of JS?</h4><p>The very minimalistic example implementation grows the built JS size by 435 kB! That is almost half a MB of minified JS!</p><p>I have no idea why would any auth library need almost half a MB of frontend code. And if this much code is included, why are the implementation details still scattered all over the application code?</p><h4>Conclusion</h4><p>I might be nitpicking here, as the setup is really simple and it works and the team was very quick to respond when I asked a question from them.</p><p>It just doesn&#8217;t give me a good feeling about how a codebase would look in the future if even the simplest possible example app looks like this. For example, in a classic, server-side rendered app (say Django or Rails), this would be 100% hidden from the developers (and also extremely well-tested by now). I understand that in a Next.js app, you have to see some of it, but this is just too much for my taste.</p><p>All in all, I decided not to use Supertokens even though I got it up and running in no time. </p><blockquote><p>In the article &#8220;<a href="https://www.ory.sh/oauth2-openid-connect-do-you-need-use-cases-examples/">Why you probably do not need OAuth2 / OpenID Connect</a>&#8221; written by the founder of Ory, he writes the following about Supertokens.</p><p>&#8220;We no longer endorse them due to a questionable choice of mixing OAuth2 terminology with self-built protocols. In particular, the use of OpenID terminology without supporting the specification itself, and the use of "access" and "refresh tokens" in incorrect contexts. We believe this to be what <a href="https://www.scottbrady91.com/blockchain-identity/technical-review-of-civics-secure-identity-platform">Scott Brady calls MyOwnOAuth&#8482;</a>.&#8221;</p></blockquote><div><hr></div><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z1dh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z1dh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png 424w, https://substackcdn.com/image/fetch/$s_!Z1dh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png 848w, https://substackcdn.com/image/fetch/$s_!Z1dh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png 1272w, https://substackcdn.com/image/fetch/$s_!Z1dh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z1dh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png" width="304" height="137.8054474708171" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:466,&quot;width&quot;:1028,&quot;resizeWidth&quot;:304,&quot;bytes&quot;:23418,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Z1dh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png 424w, https://substackcdn.com/image/fetch/$s_!Z1dh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png 848w, https://substackcdn.com/image/fetch/$s_!Z1dh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png 1272w, https://substackcdn.com/image/fetch/$s_!Z1dh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F88a40715-4757-4419-afe3-72ca1c1a2e64_1028x466.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>Ory</h2><p><a href="https://www.ory.sh/">Ory</a> is an exception in this list, the reason is very simple: after trying out all these solutions, I decided to go with Ory! Having said that, the journey was far from smooth sailing.</p><p>For example, by default, it cannot be used on a public-facing website, as the client sends an HTTP request to their service even for public users. I&#8217;ve managed to fix that behavior in a Next.js proxy, but there are half a dozen similar workarounds that are still needed today.</p><p>In the end, I decided to stay with Ory because their team was very professional and I believe those issues will be addressed soon. In my opinion, the core service is very solid, just the integration parts are having some rough edges. </p><p>I&#8217;ve decided to write my experience with Ory in a dedicated blog post, which I&#8217;ll be posting next. If you don&#8217;t want to miss it, you can subscribe here.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.hyperknot.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><p></p><h2>The ones I haven&#8217;t tried: Auth0, Keycloak, WorkOS</h2><p><a href="https://auth0.com/">Auth0</a> is the &#8220;Nobody ever got fired for buying IBM&#8221; product of Auth solutions. It&#8217;s unreasonably expensive, yet is the standard solution for Enterprise companies. Their pricing is not public above 10k MAU, but from what I&#8217;ve read they are the only company that raises the per-user cost instead of lowering it as you get bigger. Instead of offering volume discounts, you get volume &#8220;punishment&#8221;.</p><p>They are at least super safe, right? No, they got <a href="https://news.ycombinator.com/item?id=30762520">hacked</a> <a href="https://news.ycombinator.com/item?id=34077678">twice</a> in the last 12 months.</p><p><a href="https://www.keycloak.org/">KeyCloak</a> is the open-source alternative, but even seasoned ops professionals are talking about configuring it like wartime stories.</p><p><a href="https://workos.com/">WorkOS</a> - if I understand correctly - is only providing Enterprise features, like SAML. That is, it&#8217;d be used in addition to your regular auth solution, thus is not what I was looking for. BTW, they have a really strong frontend team, they are behind <a href="https://www.radix-ui.com/">Radix UI</a>.</p><p></p><h2>Synchronization</h2><p>Before I conclude this post, I want to write about the issue with synchronization: Where do you store your user&#8217;s login details?</p><p>In a classic, server-side framework like Django or Rails, of course, everything is in the production DB. You have foreign keys and everything is guaranteed to be correct and up-to-date.</p><p>Now, what happens when you start using a hosted auth solution? Half of your user&#8217;s data (email, password, SSO tokens) has to live in their DB, while the other half (the actual user-created data, subscription info, etc.) lives in your DB.</p><p>As I&#8217;ve written for Firebase, I believe constantly synchronizing these two DBs is not an easy feat. Most hosted auth products have a JSON API and webhooks that allow you to build such a solution, but it&#8217;s one of those areas where I can imagine even years into a startup&#8217;s life you will encounter bugs and edge cases.</p><p>Now, with a self-hosted version, you can actually share the same DB, as all self-hosted solutions support PostgreSQL. That alone is an amazing selling point in my opinion. Thus strangely, a paid option might be more complicated in the long run compared to a self-hosted one.</p><blockquote><p>This is one aspect where Supabase is above all the other hosted solutions: their auth uses the same DB as your application server, hence it&#8217;s a hosted auth solution where the DB is shared with your app DB.</p></blockquote><h2>Conclusion</h2><p>I&#8217;ve spent way more time finding an auth solution than I originally wanted, but I think I&#8217;ve learned a lot in the process. I started with Supabase but even after weeks of trying to make it work, the experience was so bad with random logouts that I just couldn&#8217;t consciously choose it.</p><p>After reviewing many options, I recommend the following:</p><ul><li><p>If your project can afford the pricing of <strong>Clerk</strong>, go with them.</p></li><li><p>If not and you have backend / devops experience, choose <strong>Ory</strong>. I&#8217;ll write a guide for it in the next post.</p></li><li><p>Otherwise, choose <strong>Firebase</strong>. Be aware though that the free version will probably be deprecated in the future.</p></li></ul><p>If you are interested in my experience with Ory, feel free to subscribe here, it&#8217;ll be my next post.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.hyperknot.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to <strong>Thoughts while building</strong></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>You can also contact me on <a href="https://x.com/hyperknot">X</a>, <a href="https://bsky.app/profile/hyperknot.com">bsky</a> or in <a href="mailto:blog@hyperknot.com">email</a>.</p><div><hr></div><p><strong>Update 12th Nov 2024</strong>: There was a great <a href="https://news.ycombinator.com/item?id=41923641">HN discussion</a> about this article.</p><p></p>]]></content:encoded></item></channel></rss>