<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David Cox</title>
    <description>The latest articles on DEV Community by David Cox (@david-r-cox).</description>
    <link>https://dev.to/david-r-cox</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1404460%2Fea79045b-4b98-45e6-a178-713c71d2b631.png</url>
      <title>DEV Community: David Cox</title>
      <link>https://dev.to/david-r-cox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/david-r-cox"/>
    <language>en</language>
    <item>
      <title>Changing Databases 5 Times in 48 Hours Boosted Our Launch to 35,000 Views</title>
      <dc:creator>David Cox</dc:creator>
      <pubDate>Mon, 06 May 2024 15:39:12 +0000</pubDate>
      <link>https://dev.to/supabase/changing-databases-5-times-in-48-hours-boosted-our-launch-to-35000-views-1oc2</link>
      <guid>https://dev.to/supabase/changing-databases-5-times-in-48-hours-boosted-our-launch-to-35000-views-1oc2</guid>
      <description>&lt;p&gt;The way this story begins is about as wacky as its title. I started &lt;a href="https://integrated-reasoning.com/"&gt;Integrated Reasoning&lt;/a&gt; in 2021 to find out what would happen if &lt;a href="https://docs.amd.com/r/en-US/ug1399-vitis-hls/Overview-of-Arbitrary-Precision-Integer-Data-Types"&gt;arbitrary precision&lt;/a&gt; integers could be used when solving &lt;a href="https://en.wikipedia.org/wiki/Knapsack_problem"&gt;knapsack problems&lt;/a&gt; (e.g. 9, 33, and 65 bit registers). My thinking was that a flexible word size would make &lt;a href="https://en.wikipedia.org/wiki/Pseudo-polynomial_time#Knapsack_problem"&gt;pseudo-polynomial time algorithms&lt;/a&gt; for solving knapsack problems more efficient. In short, it does help, but the largest gains come from &lt;a href="https://www.xilinx.com/developer/articles/task-level-parallelism-and-pipelining-in-hls.html"&gt;pipelining&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Fast-forward to mid-April 2024. We’d just started developing &lt;a href="https://irx.app"&gt;IRX&lt;/a&gt;, an optimization-as-a-service platform, to serve as the interface to Integrated Reasoning’s hardware accelerated solvers. We planned a MVP that essentially moved the experience of running open-source solvers like &lt;a href="https://github.com/ERGO-Code/HiGHS"&gt;HiGHS&lt;/a&gt; from the command line into the browser. The selling point being that these processes can take months or longer to complete, and not having to wrangle them would help our users focus on optimization instead of the infrastructure required to run optimization.&lt;/p&gt;

&lt;p&gt;Pushing logs in real-time from AWS to the browser was something I’d never done before. I figured it was roughly similar to the problem of &lt;a href="https://vercel.com/docs/recipes/streaming-from-llm"&gt;streaming text from an LLM&lt;/a&gt;, something I’d never done before either, which has seen tons of recent development. On one hand, real-time log events might be overkill for an MVP. On the other hand, rendering logs in real-time looks beautiful and would help us provide a user experience that’s as smooth as the command line. We went for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5ncdab8cecwrfidgv5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5ncdab8cecwrfidgv5o.png" alt="irx.app" width="800" height="786"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our initial plan was to use &lt;a href="https://www.prisma.io/docs/pulse/what-is-pulse"&gt;Prisma Pulse&lt;/a&gt; to subscribe to Postgres writes within an edge function that sent each line of stdout from &lt;a href="https://github.com/ERGO-Code/HiGHS"&gt;HiGHS&lt;/a&gt;, &lt;a href="https://github.com/coin-or/Cbc"&gt;CBC&lt;/a&gt;, and &lt;a href="https://github.com/scipopt/scip"&gt;SCIP&lt;/a&gt; to the browser using &lt;a href="https://vercel.com/docs/functions/streaming"&gt;Vercel streaming responses&lt;/a&gt;. Other than its complexity, there were two major problems with this plan. Finding a managed Postgres instance that had the right combination of &lt;a href="https://www.prisma.io/docs/pulse/database-setup/general-database-instructions"&gt;table replication functionality&lt;/a&gt; to satisfy the requirements of both Pulse and our backend was non-trivial, resulting in the absurdity that is the first half of this article’s title. The cascade of events that stemmed from changing Postgres providers five times in two days is still mind-blowing to me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42o4f7nsoane5mzl3bap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42o4f7nsoane5mzl3bap.png" alt="Ant Wilson on Twitter" width="800" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The domino effect began when Long (&lt;a href="https://x.com/beertocode"&gt;@beertocode&lt;/a&gt;) from Supabase reached out with a challenge. He explained that he wants to give new people building with Supabase an extra push. If we build and launch with Supabase within two weeks, they will use their supa-huge following on socials to make the launch a big one. Challenge accepted, and challenge it was.&lt;/p&gt;

&lt;p&gt;Social media opportunity is not usually part of the equation when evaluating database options. However, our launch goal was to gather as much user feedback as possible, so it was a factor we couldn’t ignore. Knowing almost nothing about Supabase’s product, I took an afternoon to read through all of their documentation. By that evening I had a completely different, much simpler, mental model for how to build IRX.&lt;/p&gt;

&lt;p&gt;Supabase’s &lt;a href="https://supabase.com/docs/guides/auth/auth-anonymous"&gt;anonymous sign-in&lt;/a&gt; feature coupled with &lt;a href="https://supabase.com/docs/guides/auth/row-level-security"&gt;row level security&lt;/a&gt; meant that people could use IRX on launch day without having to go through a registration process. We’re talking zero barrier to entry, which is something I didn’t even think was possible in the seemingly never ending cycle of “create another account and reset your password” that is life in 2024.&lt;/p&gt;

&lt;p&gt;Anonymous sign-in proved extremely valuable to us by making it possible for nearly three hundred people to try solving mixed-integer programs with IRX on launch day — even if they had no idea what IRX was and were just playing around. We got incredible feedback from a wider variety of backgrounds than I’d have ever imagined.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh0en2wbnzudxv7wfsbn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh0en2wbnzudxv7wfsbn9.png" alt="IRX Traffic" width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second of the two problems with our approach to real-time log streaming didn’t present itself until after we’d implemented the feature. Prisma Pulse has a limit of at most 20 concurrent subscriptions per table. This limit wasn’t obvious until a resource leak consumed our entire connection quota instantaneously. Capping out at 20 concurrent users would not have made for a good launch and time was really ticking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7banl0soa2fm39kcwqdu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7banl0soa2fm39kcwqdu.png" alt="IRX Launch Timer" width="800" height="1124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We were still debugging streaming when Long Tweeted us at the three hour mark 😅.   Fortunately by this point I’d read everything there is to read about Supabase, including their &lt;a href="https://supabase.com/docs/guides/realtime/quotas"&gt;quota table&lt;/a&gt; for &lt;a href="https://supabase.com/docs/guides/realtime"&gt;realtime events&lt;/a&gt;, which supports 10,000 concurrent clients out of the box. Making the switch was easy, largely thanks to Supabase’s TypeScript &lt;a href="https://supabase.com/docs/reference/cli/supabase-gen-types-typescript"&gt;type generation&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Other than some &lt;a href="https://sdk.vercel.ai/docs/advanced/backpressure"&gt;back pressure&lt;/a&gt; issues, we managed to ship real-time log streaming for three solvers running simultaneously on potentially different spot instances.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1lgl316idyd9vcprnz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1lgl316idyd9vcprnz8.png" alt="IRX Infrastructure" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftv7730xmmhcmn1rqcfgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftv7730xmmhcmn1rqcfgh.png" alt="IRX Solver Infrastructure" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(IRX internal infrastructure diagrams by &lt;a href="https://twitter.com/baykovr"&gt;@baykovr&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Long put it best:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1s50siph4hz53iqtpn5r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1s50siph4hz53iqtpn5r.png" alt="Long on Twitter" width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What’s really crazy is that I signed up for Resend because of their Supabase integration. Their founder &lt;a href="https://x.com/zenorocha"&gt;@zenorocha&lt;/a&gt; blew up &lt;a href="https://twitter.com/IntegrateReason/"&gt;our Twitter&lt;/a&gt; a few days before the launch, adding another 16,000 views to our launch week traffic with a single tweet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuruto1h7g5m32eum8ho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuruto1h7g5m32eum8ho.png" alt="Zeno Rocha on Twitter" width="800" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s my sketch of IRX’s infrastructure on the day of the launch:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa263k49npgp2p22ane1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa263k49npgp2p22ane1i.png" alt="IRX Launch Day Infrastructure" width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We freaking launched. Thank you for the challenge Supabase!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j5fqeqyfolulnf1ctrb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j5fqeqyfolulnf1ctrb.png" alt="Supabase on Twitter" width="800" height="904"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
