<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Adorable Engineering Blog</title>
  <subtitle>How an AI app platform that ships to production actually works.</subtitle>
  <link href="https://adorable.bot/blog"/>
  <link rel="self" href="https://adorable.bot/blog/feed.xml" type="application/atom+xml"/>
  <id>https://adorable.bot/blog</id>
  <updated>2026-06-15T00:00:00Z</updated>
  <entry>
    <title>Adorable vs. Lovable, v0, Bolt, and Replit: where your backend actually runs</title>
    <link href="https://adorable.bot/blog/adorable-vs-ai-app-builders"/>
    <id>https://adorable.bot/blog/adorable-vs-ai-app-builders</id>
    <updated>2026-06-15T00:00:00Z</updated>
    <summary>Every AI app builder now generates a working full-stack app. The category has converged on the easy 80%. What still separates these tools is three questions nobody puts on the landing page: where does your backend code actually run, what does a deploy do to your data, and how many moving parts — services and apps — can one project hold? Measured on those axes across Lovable, v0, Bolt, Replit, and us, the field splits in a way the feature grids hide.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Product"/>
    <category term="Architecture"/>
    <category term="Deployment"/>
    <category term="Postgres"/>
  </entry>
  <entry>
    <title>Anatomy of an AI app platform that ships to production</title>
    <link href="https://adorable.bot/blog/anatomy-of-an-ai-app-platform"/>
    <id>https://adorable.bot/blog/anatomy-of-an-ai-app-platform</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>Turning a prompt into a running product is not a model problem — it's a systems problem. This is the map of the whole machine: how a chat message becomes an isolated Kubernetes workload with its own scale-to-zero Postgres branch, why the agent's work is gated by compilers and live probes instead of its own opinion, and how a release becomes a database branch promotion with a rollback anchor. Every other post on this blog zooms into one box of this diagram.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Architecture"/>
    <category term="AI-agents"/>
    <category term="Kubernetes"/>
    <category term="Postgres"/>
    <category term="Deployment"/>
  </entry>
  <entry>
    <title>Deploy is a branch promotion, not a migration</title>
    <link href="https://adorable.bot/blog/deploy-is-a-branch-promotion"/>
    <id>https://adorable.bot/blog/deploy-is-a-branch-promotion</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>Shipping to production normally means moving data: dump dev, restore into a separate prod database, run the migrations, hope nothing drifted. On copy-on-write Postgres timelines it's a different shape — production is a branch, and going live is a promotion. No bytes move when prod forks from dev's head, re-deploys advance prod and apply only the pending migrations, rollback is a point-in-time branch, and each environment scales to zero independently. Here's the model and the mechanics.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Architecture"/>
    <category term="Postgres"/>
    <category term="Neon"/>
    <category term="Deployment"/>
  </entry>
  <entry>
    <title>The life of a weekend app</title>
    <link href="https://adorable.bot/blog/life-of-a-weekend-app"/>
    <id>https://adorable.bot/blog/life-of-a-weekend-app</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>One Friday evening, one casual paragraph about a ski-trip expense spreadsheet, and a platform doing everything the demo never shows. This is the true story of a single app — real prompts, real timestamps, real money — from first message to a verified, frozen, costs-nothing application. Every stop on the timeline is a door into the machinery that made it boring.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Product"/>
    <category term="AI-agents"/>
    <category term="Architecture"/>
    <category term="Postgres"/>
  </entry>
  <entry>
    <title>Why separated storage/compute Postgres is the right database for AI agents</title>
    <link href="https://adorable.bot/blog/neon-architecture-for-agentic-workloads"/>
    <id>https://adorable.bot/blog/neon-architecture-for-agentic-workloads</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>The entity creating databases is no longer a human filling out a provisioning form — it's an agent, spinning up hundreds of short-lived, mostly-idle databases. That workload breaks the assumptions a traditional Postgres-per-app is built on. Here's why storage/compute separation with copy-on-write branching and scale-to-zero is the architecture that actually fits, mapped primitive-by-primitive to what agents do.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Architecture"/>
    <category term="Postgres"/>
    <category term="Neon"/>
    <category term="AI-agents"/>
  </entry>
  <entry>
    <title>Pausing a thousand idle apps: KEDA, CRIU, and the cgroup v2 freezer</title>
    <link href="https://adorable.bot/blog/pausing-a-thousand-idle-apps"/>
    <id>https://adorable.bot/blog/pausing-a-thousand-idle-apps</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>Every app on the platform must cost nothing while nobody's looking at it — and come back instantly when someone does. We chose containers over microVMs, then tried three ways to make idle free: scale-to-zero with KEDA, checkpoint/restore with CRIU, and finally the cgroup v2 freezer with swap reclaim. The first two taught us, in very different ways, what the constraint actually was. This is the chronicle of the experiments, the failure modes we hit, and the design that survived.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Architecture"/>
    <category term="Kubernetes"/>
    <category term="Linux"/>
    <category term="Rust"/>
    <category term="Containers"/>
  </entry>
  <entry>
    <title>Scale-to-zero Postgres: a Rust proxy that wakes your database mid-connection</title>
    <link href="https://adorable.bot/blog/scale-to-zero-postgres-proxy"/>
    <id>https://adorable.bot/blog/scale-to-zero-postgres-proxy</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>Every app on the platform gets its own Postgres that costs nothing while idle — the compute scales to zero. The trick is waking it transparently on the next connection: a Rust proxy speaks the Postgres wire protocol, parks the client, scales a K8s Deployment 0→1, and forwards the query once it's live. Here's the wire parsing, the single-flight wake, and the tokio Notify registration discipline that keeps the wake correct under concurrency.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Architecture"/>
    <category term="Postgres"/>
    <category term="Rust"/>
    <category term="Kubernetes"/>
    <category term="Neon"/>
  </entry>
  <entry>
    <title>The gravity of the primary app</title>
    <link href="https://adorable.bot/blog/the-gravity-of-the-primary-app"/>
    <id>https://adorable.bot/blog/the-gravity-of-the-primary-app</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>A project on this platform isn't one app and one stack — it's N isolated apps and M services sharing a single Kubernetes namespace, all provisioned from a chat message. Once you allow that, almost every bug rhymes: a &quot;new sibling app&quot; silently collapses back into the primary one. This is the story of why that keeps happening, the single principle that fixes the whole class — converge to the declared state at one chokepoint, fail closed instead of falling back to primary — and how the same principle, run in reverse, lets us time-travel the entire stack (code in git, data in a shared Neon branch, and the live K8s infrastructure) back to one coherent moment.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Architecture"/>
    <category term="Multi-app"/>
    <category term="Kubernetes"/>
    <category term="Neon"/>
    <category term="Provisioning"/>
    <category term="Time-travel"/>
    <category term="Reconciliation"/>
  </entry>
  <entry>
    <title>The preview is not the product</title>
    <link href="https://adorable.bot/blog/the-preview-is-not-the-product"/>
    <id>https://adorable.bot/blog/the-preview-is-not-the-product</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>Every AI app builder can show you a running preview minutes after a prompt — generation is the part that got easy. The product is everything that has to hold after a stranger logs in: deploys that don't touch their data, rollback that means something, secrets nobody pasted, an idle cost of zero, and a recovery story for every way a build can die. A tour of the gap, and the design stance that closes it: the agent may be wrong; the platform may not.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Product"/>
    <category term="Architecture"/>
    <category term="AI-agents"/>
    <category term="Deployment"/>
  </entry>
  <entry>
    <title>Time-travel for code AND data: undoing an AI agent's database mistakes</title>
    <link href="https://adorable.bot/blog/time-travel-for-code-and-data"/>
    <id>https://adorable.bot/blog/time-travel-for-code-and-data</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>An AI agent will confidently run a migration that drops the wrong column. Git gives you an undo for code; nothing gives you one for data. Here's how code+data time-travel works on copy-on-write Postgres timelines — the checkpoint-at-LSN, the copy-on-write restore, and the cache coherence that keeps the compute repoint correct.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Architecture"/>
    <category term="Postgres"/>
    <category term="Neon"/>
    <category term="AI-agents"/>
  </entry>
  <entry>
    <title>Giving the agent an undo button for your data</title>
    <link href="https://adorable.bot/blog/time-travel-for-the-apps-you-build"/>
    <id>https://adorable.bot/blog/time-travel-for-the-apps-you-build</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>An AI agent that builds your app also runs migrations, bulk edits, and seeds — destructive operations that git can't undo, because git only versions code. So we gave the agent a data undo it wields itself: it snapshots before a risky operation and rolls back if the operation breaks the data. Here's how it works on copy-on-write Postgres, why restore keeps the same connection string, and why a fleet of these apps costs nothing while idle.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Product"/>
    <category term="Postgres"/>
    <category term="Neon"/>
    <category term="AI-agents"/>
  </entry>
  <entry>
    <title>What a rollback is allowed to delete</title>
    <link href="https://adorable.bot/blog/what-a-rollback-is-allowed-to-delete"/>
    <id>https://adorable.bot/blog/what-a-rollback-is-allowed-to-delete</id>
    <updated>2026-06-14T00:00:00Z</updated>
    <summary>A time-travel rollback has to land a project in a coherent state across three very different stores: git source, the live Kubernetes runtime, and a shared Postgres branch. The interesting question isn't &quot;how do we restore&quot; — it's &quot;what are we allowed to physically delete, and how do we stay reversible?&quot; The answer is a single invariant: only remove what is either recoverable from git history or regenerable from the spec, and soft-archive the one relational anchor that ties them together.</summary>
    <author><name>The Adorable team</name></author>
    <category term="Architecture"/>
    <category term="Git"/>
    <category term="Kubernetes"/>
    <category term="Rollback"/>
    <category term="Neon"/>
  </entry>
  <entry>
    <title>A real bug is a truer benchmark than a leaderboard</title>
    <link href="https://adorable.bot/blog/truer-benchmark-than-a-leaderboard"/>
    <id>https://adorable.bot/blog/truer-benchmark-than-a-leaderboard</id>
    <updated>2026-06-12T00:00:00Z</updated>
    <summary>Every model ships with leaderboard numbers. They measure one-shot deductive puzzles — and tell you almost nothing about how a model behaves when it's stuck on a real problem inside a live system. We got an unplanned head-to-head: the same prompt, the same broken file, the same running app, two models. One burned its entire budget over 51 steps re-deriving cross products by hand and never fixed it; the other fixed it in 19. The gap wasn't raw intelligence. It was *policy when stuck* — and the bug was engineered, by accident, to measure exactly that.</summary>
    <author><name>The Adorable team</name></author>
    <category term="AI-agents"/>
    <category term="Benchmarking"/>
    <category term="Model-routing"/>
    <category term="WebGL"/>
    <category term="Three.js"/>
  </entry>
</feed>
