> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Instant data cloning was a bet. AI agents are the payoff.

> How Upsun's data-first architecture, built a decade ago for CMS and e-commerce needs, turns out to be the exact infrastructure AI agents need: instant, isolated, production-identical environments with real data.


export const PostMeta = ({data = {}}) => {
  const {author, date, image} = data;
  const authors = Array.isArray(author) ? author : author ? [author] : [];
  const resolveAuthor = slug => {
    const entry = AUTHOR_MAP[slug] || ({});
    const name = entry.name || slug;
    const github = entry.github || null;
    const linkedin = entry.linkedin || null;
    const url = github ? `https://github.com/${github}` : linkedin || null;
    const avatarUrl = github ? `https://github.com/${github}.png?size=64` : null;
    return {
      name,
      url,
      avatarUrl
    };
  };
  const formattedDate = date ? new Date(date).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  }) : null;
  if (!image && authors.length === 0 && !formattedDate) return null;
  const AUTHOR_MAP = {
    "aaron-collier": {
      "name": "Aaron Collier"
    },
    "aaron-dudenhofer": {
      "name": "Aaron Dudenhofer"
    },
    "aaron-porter": {
      "name": "Aaron Porter"
    },
    "adriaan-odendaal": {
      "name": "Adriaan Odendaal"
    },
    "ajmal": {
      "name": "Ajmal Siddiqui"
    },
    "akalipetis": {
      "name": "Antonis Kalipetis"
    },
    "alexander-varwijk": {
      "name": "Alexander Varwijk"
    },
    "alicia-bevilacqua": {
      "name": "Alicia Bevilacqua"
    },
    "amelie-deguerry": {
      "name": "Amelie Deguerry"
    },
    "anacidre": {
      "name": "Ana Cidre",
      "linkedin": "https://www.linkedin.com/in/ana-cidre"
    },
    "andoni": {
      "name": "Andoni Auzmendi"
    },
    "andrei-taranu": {
      "name": "Andrei (Alex) Taranu",
      "linkedin": "https://www.linkedin.com/in/andrei-alex-taranu/"
    },
    "andrew-baxter": {
      "name": "Andrew Baxter"
    },
    "andrew-melck": {
      "name": "Andrew Melck"
    },
    "antoine-crochet-damais": {
      "name": "Antoine Crochet Damais"
    },
    "augustin-delaporte": {
      "name": "Augustin Delaporte",
      "linkedin": "https://www.linkedin.com/in/augustindelaporte/"
    },
    "branislav-bujisic": {
      "name": "Branislav Bujisic"
    },
    "carl-smith": {
      "name": "Carl Smith"
    },
    "caroline-leroy": {
      "name": "Caroline Leroy"
    },
    "cati-mayer": {
      "name": "Cati Mayer"
    },
    "catplat": {
      "name": "C Trinkwon"
    },
    "ceelolulu": {
      "name": "Celeste van der Watt"
    },
    "chadwcarlson": {
      "name": "Chad Carlson",
      "github": "chadwcarlson",
      "linkedin": "https://www.linkedin.com/in/chadwcarlson"
    },
    "chris-ward": {
      "name": "Chris Ward"
    },
    "chris-yates": {
      "name": "Chris Yates"
    },
    "christian-sieber": {
      "name": "Christian Sieber"
    },
    "christopher-lockheardt": {
      "name": "Christopher Lockheardt"
    },
    "christopher-skene": {
      "name": "Christopher Skene"
    },
    "chuck-morgan": {
      "name": "Chuck Morgan"
    },
    "corey-dockendorf": {
      "name": "Corey Dockendorf"
    },
    "crell": {
      "name": "Crell"
    },
    "damz": {
      "name": "Damz"
    },
    "dan-morrison": {
      "name": "Dan Morrison"
    },
    "davidbonachera": {
      "name": "David Bonachera",
      "github": "davidbonachera",
      "linkedin": "https://www.linkedin.com/in/davidbonachera"
    },
    "dereliahmet1": {
      "name": "Ahmet Faruk Dereli"
    },
    "devicezero": {
      "name": "Jonas Kröger",
      "github": "devicezero",
      "linkedin": "https://www.linkedin.com/in/jonaskroeger/"
    },
    "doug-goldberg": {
      "name": "Doug Goldberg"
    },
    "duncan-naves": {
      "name": "Duncan Naves",
      "github": "duncannaves",
      "linkedin": "https://www.linkedin.com/in/duncan-naves-a94423aa"
    },
    "erika-bustamante": {
      "name": "Erika Bustamante"
    },
    "fabpot": {
      "name": "Fabien Potencier"
    },
    "flovntp": {
      "name": "Florent Huck",
      "github": "flovntp",
      "linkedin": "https://www.linkedin.com/in/florenthuck"
    },
    "fred-plais": {
      "name": "Fred Plais"
    },
    "gauthier-garnier": {
      "name": "Gauthier Garnier"
    },
    "gilzow": {
      "name": "Paul Gilzow"
    },
    "gmoigneu": {
      "name": "Guillaume Moigneu",
      "github": "gmoigneu",
      "linkedin": "https://www.linkedin.com/in/guillaumemoigneu/"
    },
    "gregqualls": {
      "name": "Greg Qualls"
    },
    "guguss": {
      "name": "Augustin Delaporte"
    },
    "haylee-millar": {
      "name": "Haylee Millar"
    },
    "ivana-kotur": {
      "name": "Ivana Kotur"
    },
    "jackrabbithanna": {
      "name": "Mark Hanna"
    },
    "jared-wright": {
      "name": "Jared Wright",
      "github": "jww-sh",
      "linkedin": "https://www.linkedin.com/in/jaredwaynewright"
    },
    "jessica-orozco": {
      "name": "Jessica Orozco"
    },
    "joey-stanford": {
      "name": "Joey Stanford"
    },
    "john-grubb": {
      "name": "John Grubb"
    },
    "jonas-kruger": {
      "name": "Jonas Kruger"
    },
    "kathryn-frazer": {
      "name": "Kathryn Frazer"
    },
    "kemiojo": {
      "name": "Kemi Elizabeth Ojogbede"
    },
    "kieronsambrook-smith": {
      "name": "Kieronsambrook Smith"
    },
    "laurent-arnoud": {
      "name": "Laurent Arnoud",
      "linkedin": "https://www.linkedin.com/in/laurent-arnoud-861b44121/"
    },
    "letoya-boyne": {
      "name": "Letoya Boyne"
    },
    "lolautruche": {
      "name": "Jérôme Vieilledent"
    },
    "lyly-lepinay": {
      "name": "Lyly Lepinay"
    },
    "manauwar-alam": {
      "name": "Manauwar Alam"
    },
    "marc-antoine-porri": {
      "name": "Marc Antoine Porri"
    },
    "maria-antinkaapo": {
      "name": "Maria Antinkaapo"
    },
    "maria-de-anton": {
      "name": "Maria De Anton"
    },
    "mark-dorison": {
      "name": "Mark Dorison"
    },
    "markus-hausammann": {
      "name": "Markus Hausammann"
    },
    "mary-thomas": {
      "name": "Mary Thomas"
    },
    "mathias-bolt-lesniak": {
      "name": "Mathias Bolt Lesniak"
    },
    "mathieu-strauch": {
      "name": "Mathieu Strauch"
    },
    "matthias-van-woensel": {
      "name": "Matthias Van Woensel",
      "linkedin": "https://www.linkedin.com/in/matthias-van-woensel-267a069"
    },
    "michael-sharp": {
      "name": "Michael Sharp"
    },
    "mupsi": {
      "name": "Marine Gandy"
    },
    "natalie-harper": {
      "name": "Natalie Harper"
    },
    "ngommenginger": {
      "name": "Nicolas Gommenginger",
      "linkedin": "https://www.linkedin.com/in/nicolas-gommenginger"
    },
    "nicholas-bennison": {
      "name": "Nicholas Bennison"
    },
    "nicholas-vahalik": {
      "name": "Nicholas Vahalik"
    },
    "nick-hardiman": {
      "name": "Nick Hardiman"
    },
    "nickanderegg": {
      "name": "Nickanderegg"
    },
    "nicolas-grekas": {
      "name": "Nicolas Grekas",
      "github": "nicolas-grekas",
      "linkedin": "https://www.linkedin.com/in/nicolasgrekas/"
    },
    "niti-malwade": {
      "name": "Niti Malwade"
    },
    "opensocialteam": {
      "name": "Opensocialteam"
    },
    "ori-pekelman": {
      "name": "Ori Pekelman"
    },
    "otavio-santana": {
      "name": "Otavio Santana"
    },
    "palwandi": {
      "name": "Pawan Alwandi",
      "github": "pawpy",
      "linkedin": "https://www.linkedin.com/in/pawanalwandi"
    },
    "patrick-boest": {
      "name": "Patrick Boest"
    },
    "patrick-dawkins": {
      "name": "Patrick Dawkins",
      "github": "pjcdawkins",
      "linkedin": "https://www.linkedin.com/in/patrickdawkins"
    },
    "patrick-klima": {
      "name": "Patrick Klima"
    },
    "pjcdawkins": {
      "name": "Pjcdawkins"
    },
    "prineet-kaurbhurji": {
      "name": "Prineet Kaurbhurji"
    },
    "quentin-sinig": {
      "name": "Quentin Sinig"
    },
    "ralt": {
      "name": "Florian Margaine",
      "github": "ralt",
      "linkedin": "https://www.linkedin.com/in/florian-margaine-43971136"
    },
    "ramanathanramakrishnamurthy": {
      "name": "Ramanathanramakrishnamurthy"
    },
    "remi-lejeune": {
      "name": "Rémi Lejeune"
    },
    "ribel": {
      "name": "Taras Kruts"
    },
    "robert-douglass": {
      "name": "Robert Douglass"
    },
    "rudy-weber": {
      "name": "Rudy Weber"
    },
    "ryan-hicks": {
      "name": "Ryan Hicks"
    },
    "sabri-helal": {
      "name": "Sabri Helal"
    },
    "savannah-bergeron": {
      "name": "Savannah Bergeron"
    },
    "shannon-vettes": {
      "name": "Shannon Vettes"
    },
    "shawn-ogasawara": {
      "name": "Shawn Ogasawara",
      "linkedin": "https://www.linkedin.com/in/shawn-ogasawara-83a9a0/"
    },
    "shawna-spoor": {
      "name": "Shawna Spoor"
    },
    "shedrack-akintayo": {
      "name": "Shedrack Akintayo"
    },
    "simon-ruggier": {
      "name": "Simon Ruggier"
    },
    "sophie-van-der-kindere": {
      "name": "Sophie Van Der Kindere"
    },
    "stefanos-thampis": {
      "name": "Stefanos Thampis"
    },
    "stephen-weinberg": {
      "name": "Stephen Weinberg"
    },
    "sukhman-virk": {
      "name": "Sukhman Virk"
    },
    "sumaira-nazir": {
      "name": "Sumaira Nazir"
    },
    "sumer": {
      "name": "Sümer Cip"
    },
    "syed-raza": {
      "name": "Syed Raza"
    },
    "tamara-bacchia": {
      "name": "Tamara Bacchia"
    },
    "tara-arnold": {
      "name": "Tara Arnold"
    },
    "theosakamg": {
      "name": "Mickael Gaillard",
      "github": "theosakamg"
    },
    "thomasdiluccio": {
      "name": "Thomas di Luccio"
    },
    "tim-anderson": {
      "name": "Tim Anderson"
    },
    "tom-helmer-hansen": {
      "name": "Tom Helmer Hansen"
    },
    "tylermills": {
      "name": "Tyler Mills"
    },
    "upsun": {
      "name": "Upsun"
    },
    "veronika-tolkachova": {
      "name": "Veronika Tolkachova",
      "linkedin": "https://www.linkedin.com/in/veronika-tolkachova-169167a2"
    },
    "vince-parker": {
      "name": "Vince Parker"
    },
    "vinnie-russo": {
      "name": "Vincenzo Russo"
    },
    "vrobert78": {
      "name": "Vincent Robert",
      "github": "vrobert78",
      "linkedin": "https://www.linkedin.com/in/vincent-robert-498a883"
    },
    "yuriy-babenko": {
      "name": "Yuriy Babenko"
    },
    "yuriy-gerasimov": {
      "name": "Yuriy Gerasimov"
    }
  };
  return <div className="post-meta">
      {(authors.length > 0 || formattedDate) && <div className="post-meta-info">
          {authors.length > 0 && <div className="post-meta-authors">
              {authors.map(slug => {
    const {name, url, avatarUrl} = resolveAuthor(slug);
    const inner = <>
                    {avatarUrl && <img src={avatarUrl} alt={name} className="post-meta-avatar" />}
                    <span className="post-meta-author-name">{name}</span>
                  </>;
    return url ? <a key={slug} href={url} target="_blank" rel="noopener noreferrer" className="post-meta-author">
                    {inner}
                  </a> : <span key={slug} className="post-meta-author">{inner}</span>;
  })}
            </div>}
          {authors.length > 0 && formattedDate && <span className="post-meta-separator" aria-hidden="true">·</span>}
          {formattedDate && <span className="post-meta-date">{formattedDate}</span>}
        </div>}
      {image && <img src={image} alt="" className="post-meta-image" aria-hidden="true" />}
    </div>;
};

<PostMeta data={{ author: ["augustin-delaporte"], date: "2026-02-24T07:00:00.000Z", image: "/images/posts/discussions/instant-data-cloning-was-a-bet-ai-agents-are-the-payoff/data-cloning-agents.webp" }} />

A bit over ten years ago, a small team inside a Drupal Commerce agency made a decision that seemed, at the time, wildly ambitious: **deployments should include data**. Not "data as an afterthought." Not "here's a script to restore a database dump." Data as a first-class citizen of every environment, instantly cloned alongside code, services, and files in one atomic operation.

That bet took two years of R\&D. At the time, Docker wasn't standard. Kubernetes didn't exist. The competition was Heroku, and Heroku was great at deploying code, but code alone wasn't enough. If you ran a CMS like Drupal, your content lived in the database. If you ran a Magento store, you couldn't load-test a storefront without production-scale catalog data. The same goes for [JCR-based apps](https://devcenter.upsun.com/posts/hands-on/stop-testing-jcr-apps-in-production) like Adobe Experience Manager or Magnolia, where the entire content structure, templates, and workflows live in the repository. The team needed automated deployments that carried the full stack: applications, services, files, and data. So they built it.

It wasn't a moonshot for a future driven by AI, or some grand infrastructure vision. It was a practical response to real problems: CMS content is meaningless without its database, e-commerce performance testing is fiction without production data... The motivation was mundane. The engineering was not.

## What cloning the data actually gives you

When you branch an environment on Upsun, the platform snapshots the metadata of your runtimes (frontend, backend, API server...), services (databases, message queues...), and files. It doesn't copy bytes. That's why cloning takes a couple of seconds whether your database is 500 MB or 500 GB. You get a fully independent preview environment (with its own URL, its own resources, its own permissions...) with zero interconnection to the source. Delete something in the clone, the original doesn't notice.

This exact same mechanism powers other Upsun key capabilities like:

* Branching, which creates a new preview environment from an existing one (like production).
* Backups, which capture a point-in-time snapshot that can be confidently restored.
* Synchronizing, which pulls fresh data from a parent environment.

Different use cases, same copy-on-write foundation.

And speed matters much more than you'd think. A clone that takes 30 minutes is a clone you avoid creating. A clone that takes 8 seconds is a clone you create without thinking about it. That difference changes behavior, and changing behavior is where infrastructure decisions compound.

## Agents need the same primitives

Today, AI agents have moved from "generate a code snippet" to "take this task, figure out what to do, and do it". That shift changed what agents need from infrastructure. A code suggestion can run in a sandbox or on a local machine. An agent that modifies database schemas, runs migrations, or load-tests an API endpoint needs a real environment with real data, real config, and real running services.

The requirements look familiar: an isolated environment that mirrors production, created fast enough to be disposable, destroyed when the task is done. That's what Upsun's cloning gives you. An agent gets a full copy of production (data, services, config) in seconds. It works against real state, not a synthetic approximation. When it's done, the environment disappears.

This isn't a feature built for AI. It's a feature built ten years ago that happens to be what AI agents need today.

## Reproducing bugs: the user\_7 problem

My own staff user account at Upsun ([user\_7@example.com](mailto:user_7@example.com)) has years of migration history baked into it. Every schema change, every feature flag toggle, every edge case in billing logic accumulated over time in that account's data. User 7 triggers bugs that nobody else can reproduce, because no fresh test account carries that history.

You can't fake this with seed data. You can't write a fixture that recreates years of organic state transitions. The only way to reproduce user 7's bugs is to test against user 7's actual data.

With Upsun data cloning, an agent grabs a full copy of the production environment (user 7 and all), branches it, and starts testing. It can mutate data, break things, try every combination of inputs, and the original environment stays untouched. When the agent identifies the root cause, it reports back. The clone gets deleted. No production risk, no manual environment setup, no waiting for a database dump to finish importing.

## Performance optimization without touching production

You can't measure real query performance against a test database with 50 rows. You can't profile cache hit rates without production traffic patterns reflected in the data. Performance work needs production-like conditions, and faking those conditions is a losing game.

Upsun data cloning solves this cleanly. Clone the production environment, upsize the preview environment to match production resources, then point a load-testing tool at it. Run [Blackfire](https://www.blackfire.io/) profiling against realistic traffic. Get measurable, actionable recommendations: this query needs an index, this loop should be batched, this cache TTL is too aggressive.

An agent automates this entire loop. Clone, configure, run the load test, collect profiling data, analyze results, present a ranked list of optimizations with projected impact. No one touches production. The environment gets thrown away when the analysis is done.

## Isolation and data safety

Giving an agent access to production data means thinking about PII. If the agent runs on a third-party AI provider's infrastructure, you probably don't want customer emails and credit card tokens flowing through someone else's model. But there's a tension here: scrub too aggressively and you lose the exact data quirks that make cloning valuable for bug reproduction in the first place.

It's your call. You can [configure sanitization rules](https://docs.upsun.com/development/sanitize-db.html) that run automatically when data is cloned into a non-production environment, choosing which fields get anonymized and which stay intact. Some teams scrub everything sensitive. Others keep more data in tightly controlled environments where agents operate under strict access policies. The point is that the mechanism exists at the cloning step, so you make the trade-off once and it applies to every clone.

Permissions matter too. Upsun supports fine-grained access control at the environment-type level. A production environment can have a completely different permission set than a staging or development environment. API tokens can be scoped so that an agent gets write access to its clone but can't touch production. This isn't a bolt-on; it's how the permission model has always worked.

## The payoff

Metadata-level cloning, copy-on-write storage, full-stack environment branching, configurable data sanitization. These are the building blocks of agent-ready infrastructure, and they've been in production for a decade. Upsun doesn't need to bolt on agent support because the foundation was already there.

It's a funny thing about infrastructure bets. The ones that age well aren't usually the ones that predicted the future correctly. They're the ones that solved a real, immediate problem with enough generality that the solution turned out to be useful for problems nobody anticipated. Cloning production data in seconds was built for CMS editors and e-commerce teams. It turns out AI agents need the exact same thing.

The bet paid off. Not because anyone predicted this particular use case, but because solving one hard problem well tends to stay useful longer than you'd expect.
