# Anonymised production data without the vendor bill

- URL: https://alasco.tech/2026/08/05/anonymised-production-data-with-dumpster/
- Date: 2026-08-05T00:00:00.000Z
- Authors: Bahram Aghaei
- Description: Why we moved from Tonic.ai and Neosync to Dumpster — a thin wrapper around Greenmask that anonymises our production database once per week and restores it on demand to pull request stacks.

Every SaaS team needs production-shaped data in development. But copying a live database leaks [personally identifiable information](https://en.wikipedia.org/wiki/Personal_data) (PII) and breaks regulations. After Tonic.ai proved too expensive and Neosync's cloud platform shut down in August 2025, we built **Dumpster**: a self-hosted pipeline around [Greenmask](https://www.greenmask.io/) that anonymises production once per week and restores it on demand.

## Background

Every engineer wants a development environment that looks exactly like the customer's. For instance, before you ship a database migration, you want to test it against the same schema and data volume, but not on the production. However data protection regulations make that impossible: you can't just clone production.

We started with Tonic.ai, which copied our production database into feature branches and anonymised PII along the way.

The Tonic offers a nice user interface (UI) which scan schema, flags PII columns, assigns a transformer in the UI later you can correct it if it was wrong.

In 2025 we looked for a cheaper alternative and landed on [Neosync](https://www.neosync.dev/). We evaluated it against three requirements:

- Copy production data into multiple environments (staging, development)
- Subset the database to reduce sync time
- Autodetect PII without manual column mapping

Neosync was under heavy development and their team gave us excellent support. Two of our requirements never quite landed: subsetting the production database was unreliable, and autodetect PII still meant manually identifying and mapping sensitive columns table by table.

Neosync was acquired and its cloud platform shut down in August 2025. We evaluated self-hosted alternatives and landed on [Greenmask](https://www.greenmask.io/) — open source, PostgreSQL-native, with declarative transforms similar to the UI-driven rules we had used before.

## Homegrown solution

We still map PII fields manually — same as with Neosync — but we stopped chasing database subsetting once export size proved manageable.
The bigger shift was splitting the work into two stages:

- **Dump and anonymise**: a scheduled job writes an anonymised snapshot to S3, ready before anyone asks for it.
- **Restore on demand**: pull request (PR) stacks pull the latest dump without re-running anonymisation.

That two-stage split turned out to be very beneficial: restore time dropped from **4.5 hours to under one hour**, because anonymisation happens on a schedule.

## Architecture

Greenmask does the heavy lifting: dump, anonymise, restore. **Dumpster** is a thin wrapper that wires it into our existing stack: scheduled cron jobs, background workers, a command-line interface (CLI), and PR deploy hooks.

Every Sunday at midnight, a cron job dumps the database from a read replica through Greenmask, applying transforms from a YAML config, and writes a compressed dump to S3. Six hours later, a cleanup job keeps only the two most recent successful dumps.

Greenmask uses `SET TRANSACTION SNAPSHOT` so parallel dump workers see a consistent view of the database. Every connection during a dump has to hit the same server, so we pin Greenmask to the first read-only replica in our RDS cluster rather than letting the pool round-robin across replicas.

<div class="not-prose mx-auto max-w-2xl [&_img]:block [&_img]:h-auto [&_img]:w-full [&_img]:max-w-full">

![Anonymised production snapshot pipeline](./images/dumpster-dump.png)

</div>

Restores are on-demand via CLI or by adding a `deploy-dump` label to a PR — and post status to Slack.

<div class="not-prose mx-auto max-w-2xl [&_img]:block [&_img]:h-auto [&_img]:w-full [&_img]:max-w-full">

![Dumpster restore path](./images/dumpster-restore.png)

</div>

What we once configured in the Tonic and Neosync UIs — which tables to exclude and how to transform each PII field — now lives in a YAML file bundled with the codebase:

For example, contacts get fake names via the `RandomPerson` transformer:

```yaml
  transformation:
    - schema: "public"
      name: "core_contact"
      transformers:
        - name: "RandomPerson"
          params:
            columns:
              - name: "first_name"
                template: "{{ .FirstName }}"
              - name: "last_name"
                template: "{{ .LastName }}"
```

## Takeaways

In hindsight, we unintentionally followed the "buy first, build later" approach which worked remarkably well. Both Tonic.ai and Neosync not only saved us time but also taught us about the complexity of data obfuscation and more importantly which requirements actually mattered to our engineers.

In the end, Dumpster is a glue around several open-source projects (Greenmask, Postgres), that has substantially reduced our operational costs while providing the best developer experience for our engineers.

## Acknowledgements
A huge thank you to all the members of the Platform team at Alasco for supporting us throughout this journey!