← All Notes

Platform churn and the ceiling nobody talks about

vision·March 15, 2026

A firsthand account of moving through three platforms over a decade — including serving as a reference client, design consultant, and podcast guest for two of them — and what it eventually made clear.

adrien-olichon-RCAhiGJsUUE-unsplash

Why migrations fail and what it costs

Platform migrations in the nonprofit sector carry a specific kind of dread that is entirely earned. Most organizations that have been through one have experienced at least one of the following: donor records that arrived deduplicated in ways that lost giving history, recurring subscriptions that had to be manually recreated because the export format didn't carry subscription metadata, campaign data that exported cleanly but couldn't be imported anywhere because the receiving platform used a completely different data model, or a cutover period where live donations were processing through the old system while the new one wasn't quite ready, creating reconciliation headaches that lasted for months.

These are not edge cases. They are the standard experience of nonprofit platform migration because the platforms that hold the data have no structural incentive to make leaving easy. The export tools they provide are designed to satisfy the technical requirement of data portability while doing as little as possible to make that data portable in practice. A CSV of donor records with inconsistent field naming, no relational structure, and no documentation of what any column means is technically an export. It is not a migration tool.

The cost of a bad migration compounds. Lost giving history means you can't accurately identify major donor prospects. Broken recurring subscriptions means monthly revenue that has to be recovered through re-enrollment campaigns with imperfect success rates. Incomplete campaign data means your historical fundraising benchmarks are gone and every future campaign is being planned without a reliable baseline.

The platforms that hold your data have no structural incentive to make leaving easy. The export tools they provide are designed to satisfy the technical requirement of data portability while doing as little as possible to make that data portable in practice.

What Manna built to fix this

Because the migration experience is consistently one of the biggest barriers to organizations making a platform change they know they need to make, Manna built a dedicated CLI migration tool with connectors for the platforms most organizations are moving off of. The tool is not a data export formatter. It is a structured migration pipeline that maps source data to Manna's schema, validates the output before a single record is written, and produces a complete audit log of every decision made during the migration process.

The current connectors cover Classy and Funraise, the two platforms where the migration problem is most consistently painful and where the data models are complex enough that a manual CSV approach produces systematic data loss even when done carefully. Additional connectors are in development based on where organizations are actually coming from when they approach Manna.

Contact deduplication using email address as the primary key with name similarity scoring for records without matching emails. Giving history reconstruction from transaction-level data, including attribution of historical gifts to the correct contact after deduplication. Recurring subscription metadata migration including plan amounts, intervals, and status. Campaign and fundraiser records with their associated goal and total data. Salesforce contact ID preservation for organizations with an existing Salesforce integration, so the CRM sync doesn't require re-mapping after migration.

The migration process in practice

A Manna migration runs in phases. The first phase is entirely non-destructive, which means nothing in the source platform is touched and nothing is written to the destination until the validation phase is complete. This allows the migration to be run in preview mode as many times as necessary before a single record moves.

The CLI authenticates to the source platform's API and pulls contacts, transactions, recurring plans, and campaign data into a local staging environment. No data is written anywhere during this phase. The raw export is stored locally for audit purposes.

Contacts are deduplicated using email as the primary key. Records without email addresses are grouped by name similarity and flagged for manual review rather than automatically merged, because automated merging on name similarity alone introduces its own data quality problems. Every deduplication decision is logged with the reason for the merge or the reason for the flag.

Source fields are mapped to Manna's schema. The validator checks for required fields, data type consistency, referential integrity between contacts and their associated transactions, and reasonable value ranges that flag obvious data quality problems before they enter the destination database. The validation report is human-readable and surfaces every issue that would affect the migration outcome.

The migration runs against the destination database in a preview mode that simulates every write operation without committing any of them. The preview report shows exactly what would be created, updated, or skipped, and why. Organizations can run the preview as many times as needed, adjusting configuration and reviewing the output until they are satisfied with what the migration will produce.

The production migration runs with the same configuration that passed preview validation. After completion, the tool runs a verification pass that compares source record counts against destination record counts for every entity type and flags any discrepancy for investigation. The migration is not considered complete until the verification pass is clean.

After the donor records are in place, Manna's nightly scoring engine runs against the imported giving history to initialize engagement scores for every contact. Organizations that arrive with years of giving history don't start with a blank scoring slate. The historical data is immediately working as intelligence, not just as a record archive.

A real example: The Phoenix

The Phoenix migration from Classy involved 3,200 donor records and $199,000 in giving history accumulated over multiple years of active fundraising. The complexity was not unusual for an organization of that size, but it included several characteristics that a manual CSV migration would have handled poorly.

The giving history included multi-year recurring donor records where the subscription metadata needed to migrate intact so that donor tenure calculations would be accurate in Manna's engagement scoring model. It included peer-to-peer fundraiser records from multiple campaign cycles that needed to be associated with the correct donor profiles rather than treated as standalone transaction records. And it included a set of contacts that had duplicate records in the Classy database accumulated over years of event registration and campaign participation, which the deduplication phase resolved into unified profiles with complete consolidated giving histories.

The cutover happened during a low-traffic period on a Sunday morning. Donations that processed in the hours before cutover were reconciled from Classy's webhook logs and imported as the final batch before the DNS change. The Phoenix's team opened their admin dashboard on Monday morning to a complete platform with their full donor history in place and their engagement scores already initialized from the imported data.

Complete contact records with all associated giving history. Recurring subscription relationships, intact. Campaign and peer-to-peer fundraiser records attributed correctly to donor profiles. Salesforce contact ID mappings if a Salesforce integration exists, so CRM sync resumes without re-mapping. All of it in an independent database that belongs to the organization from the moment the migration completes.

What the CLI looks like to run

The tool is designed to be run by someone comfortable with a command line but does not require deep engineering expertise to operate. The configuration is a single JSON file that specifies the source platform credentials, the destination database connection, and the options for deduplication behavior and field mapping overrides. The commands are self-documenting with help output at every step.

Every command produces a structured log file alongside its terminal output. The logs are designed to be readable by a non-technical stakeholder who needs to understand what happened during the migration without parsing raw data. The verification report in particular is written to be shared internally as documentation that the migration completed successfully and with full data integrity.

What organizations should do before starting

The quality of a migration is bounded by the quality of the source data. Before running the tool against a production export, it's worth auditing the source platform for a few specific issues that consistently surface during migrations.

Duplicate contact records are the most common problem. Most platforms accumulate duplicates over years of event registration, campaign participation, and direct mail import, because each of those entry paths creates new records rather than matching to existing ones. The deduplication phase of the migration tool handles this systematically, but reviewing the validation report's deduplication decisions before the production run is worth the time. Automated deduplication on email match is reliable. Deduplication on name similarity requires a human judgment call on the flagged records.

Giving history gaps are the second issue. Platforms that have been through their own migrations or that have had API-based import processes sometimes have transaction records without complete contact associations. These orphaned transactions can represent real giving history that is important to preserve. The validation report surfaces them explicitly so they can be investigated and resolved before the production migration runs.

Recurring subscription status is the third. Some platforms mark canceled subscriptions inconsistently, and a record that shows as active in the platform UI may have a canceled status in the API export. Running the validation report against subscription records before migration prevents canceled plans from being created as active subscriptions in the destination database.




The fear of migration is one of the most effective reasons organizations stay on platforms that are not serving them well. The cost of staying, measured in constrained campaigns, workaround-dependent processes, and platform fees that compound year over year, is consistently higher than the cost of migrating when the migration is handled with the right tooling and the right process.

Manna built the migration tooling because we have been through enough migrations, both as an organization and as a platform builder, to know that the process doesn't have to be as painful as the industry has made it. The data is yours. Moving it should not require leaving significant parts of it behind.

Work with Manna

We're accepting a limited number of new partners.

If you're a nonprofit that has outgrown your current platform, or building from scratch and want to do it right, we'd love to hear about your mission.

Tell us about your mission