How to migrate from Attio to Twenty without losing records or relations
Moving from Attio to self-hosted Twenty is a data and configuration project more than a software install. Standing up Twenty with Docker Compose is the smaller part of the work. The effort depends on how many objects, list views, relations and automations your workspace runs, and on how much of your pipeline logic lives in custom fields rather than in standard records. Internal admins with some engineering support can often handle a small workspace. Larger or more heavily customized workspaces usually go to an implementation partner, who scopes the work in writing before starting. The two areas most likely to need rebuilding are enriched fields, which may export blank, and automations, which do not carry over as they are and must be recreated and retested in Twenty.
Begin by inventorying what you have in Attio: every object, every custom attribute, every relation between objects, every list and saved view, and every workflow that writes to or reads from records. Map each one to its counterpart in Twenty, which supports custom objects and fields defined as code, workflow automation, role-based permissions and multiple workspaces. Confirm with the Twenty documentation and your own test environment how each attribute type, relation cardinality and permission rule translates, because Twenty's data model is not a one-to-one copy of Attio's. Plan the import order so that parent objects such as companies exist before the people or deals that reference them. Keep the export files and a record of record counts per object so you can reconcile totals after each import.
Plan for the risk areas before you start moving data. For enriched data, assume that values pulled from third-party providers will not come across as usable fields and that you will need to re-enrich from the source, export them separately as values, or accept their loss. Ask your vendor and your Attio administrator to confirm exactly what is excluded from export. For automations, document each trigger, condition and action, then rebuild them in Twenty's workflow automation and test them with sample records before connecting live email or calendar sync. Check that the self-hosting stack meets Twenty's requirements, including the Docker Compose guide's minimum of 2 GB of RAM, and that PostgreSQL and Redis backups run before cutover. Run a parallel period, reconcile counts and relations, then switch users over with a documented rollback plan.
Which Attio capabilities map to Twenty, and which need rework
This table compares each major Attio capability with its closest Twenty equivalent and marks it as clean, needs rework or gap. Read the status column first, then use the confirmation column to plan a test import. Most rows need rework because objects, views, automations and integrations are rebuilt by hand, and enriched fields need a new data source.
| Attio capability | Twenty equivalent | Status | What to confirm in your setup |
|---|---|---|---|
| Objects and custom attributes | Custom objects and fields defined as code, unlimited on all plans | Clean | Field types, names and required flags match your schema before import |
| Records and relations | Relations between custom and standard objects | Needs rework | Relation direction and many-to-many links are recreated before records are imported |
| List views | Object views with filters, sorts and columns | Needs rework | Each saved Attio list has a matching Twenty view with the same filters and columns |
| Enriched data fields | No enrichment carried over; exported enriched fields arrive blank | Gap | Which enrichment provider replaces each field, and whether you hold its API key and terms |
| Workflow automation | Workflow automation with triggers and actions | Needs rework | Trigger events, action steps and any connected external services are rebuilt and tested |
| Email and calendar sync | Email and calendar sync | Needs rework | Mail provider, account authorization and how much history syncs after cutover |
| Permissions | Role-based permissions; row-level permissions and SSO are listed on Twenty's paid cloud plans | Needs rework | Whether row-level permissions and SSO apply to your self-hosted build, and how roles map |
| Workspaces | Multiple workspaces | Clean | Workspace split matches how your Attio teams and data are separated today |
| API access | GraphQL and REST APIs with webhooks | Needs rework | Every integration built on Attio endpoints is rewritten against Twenty's API |
What data can move and which integrations must be rebuilt
Most of the Attio data you move will come out through CSV or Excel exports of each object and list view. Enriched fields, automations and connected inboxes need separate handling, because they do not travel as plain records.
Object and list view exports
Attio exports are built from objects and list views, so each object (people, companies, deals and any custom objects) and each saved view needs its own export. Records come out with their standard attribute values, which become the basis for the Twenty import. Confirm the export scope in your Attio workspace before planning, including which objects your role can export and whether any view filters hide records you still need.
Enriched fields that export blank
Enriched fields may export blank, so do not assume a complete CSV holds every attribute you see on screen. Data pulled in by enrichment or third-party lookups may have to be captured again through its source, or recorded in a separate file before you leave. List the enriched attributes per object and test one record end to end before you decommission anything.
Relations and custom objects
Record references between objects, such as a person linked to a company or a deal linked to a person, appear in exports only in the form Attio exposes them. Plan to recreate each custom object and relation in Twenty first, then import parent records before children so the links resolve. Check a sample of linked records after each import.
Workflows and automations
Automations do not move as data. Workflows, triggers, record-change rules and any scheduled tasks must be written again in Twenty's workflow automation, using the same conditions and actions. Document each automation from Attio, mark which ones your team still uses, and test each rebuilt workflow against a copy of the imported data.
Connected inboxes and calendars
Email and calendar connections belong to user accounts, so they must be reauthorized in Twenty rather than transferred. Historical email threads stored in Attio may not come across in a CSV, so decide with your team whether to keep an archive. Twenty supports email and calendar sync, so confirm how each user's mailbox and calendar will reconnect before cutover.
Integrations and API clients
Attio API tokens, webhooks and third-party integrations are tied to the old account and will stop working when you cut over. Inventory every system that reads from or writes to Attio, then point each one at Twenty's REST or GraphQL API and test it with a non-production key. Confirm the endpoints and authentication methods for each integration in Twenty's documentation.
The migration sequence from inventory to decommission
This sequence moves Attio data into a self-hosted Twenty instance in controlled stages, so each object is proven before the full dataset moves. It ends with Attio retired only after a final export is retained and the cutover is signed off.
Inventory objects, list views, relations and automations
Before any export, list every standard and custom object in Attio, every list view that teams rely on, each relation between objects, and every workflow, integration and webhook that reads or writes records. Record the owner of each item and which team uses it daily. Attio's own export is organized view by view, so the list views matter here as well as the objects behind them. The output is a field mapping sheet that pairs each Attio object and attribute with its planned Twenty object and field, marks enriched or computed fields that may not export, and flags automations that must be rebuilt. The step is done when the business owner for each object has signed off on the mapping sheet.
Stand up the Twenty instance in your infrastructure
Deploy Twenty on infrastructure your organization controls, using the Docker Compose self-hosting guide as the starting point for the server, worker, PostgreSQL and Redis services. Confirm the host meets the guide's stated memory minimum and set up backups for the database before any data is loaded. Your platform team owns hosting, and the CRM administrator owns workspace configuration. Recreate the custom objects and fields from the mapping sheet in a test workspace, not the production one. The output is a running staging instance with a documented configuration and a tested backup and restore.
Run a pilot import of one object
Choose one low-risk object, such as companies or a small custom object, and export it from Attio view by view. Import it into the staging Twenty workspace, following the field mapping sheet, and rebuild its relations to other objects. Check which fields came back blank, particularly enriched data, and decide with the business owner whether to re-enrich, re-enter or accept the gap. The output is a pilot reconciliation report that compares record counts, required fields, relation links and sample records between the two systems. Do not start the full migration until the report has been reviewed and the import steps are documented as repeatable.
Import the remaining objects and run in parallel
Import the other objects in the order their relations require, so that parent records exist before linked records. Rebuild the list views and the automations flagged in the inventory in Twenty, and test each one against the staging data. Then run both systems side by side for a defined period agreed in advance, with every record assigned to one owner who is the system of record for it during that period. Entry and edits go to the owning system, and any change in the other system is reconciled. The output is a parallel run log and a list of discrepancies with their resolution. The step is complete when the discrepancy list is empty or every open item has an agreed owner and date.
Freeze Attio and complete the final export
Announce a write freeze in Attio, after which no one edits or creates records there. Run the complete export again from every object and list view, covering the same scope as the inventory, and run a final delta import into Twenty for anything changed since the pilot. Repeat the reconciliation against the frozen export and confirm the counts and relation links match. Cutover should be approved against a written checklist that names the approver for the CRM, the data owner and the security owner. The output is a signed cutover checklist and a final reconciliation report.
Retain a final export and decommission Attio
Before you cancel or downgrade Attio, store the frozen final export, the export logs and the mapping sheet in an archive your organization controls, with access limited to named roles. Confirm with your contract owner which Attio data retention and deletion terms apply after cancellation, and confirm them in writing with the vendor. Revoke Attio integrations, API keys and user access only after the archive has been verified by restoring a sample. The output is a retained archive with a verified restore test, an access list, and a decommission record that the CRM owner and security owner have both signed.
Setting up a self-hosted Twenty instance for the cutover
Before any data moves, the team needs a running Twenty instance with a defined hosting footprint. Twenty's Docker Compose self-hosting guide runs four components: a server, a worker, PostgreSQL and Redis. The guide asks for at least 2 GB of RAM, and it warns that insufficient memory can crash processes. For a cutover, treat that figure as the floor, not the target. Import jobs create many records and run workflows at the same time, so plan a staging instance sized like production and load-test it with a copy of the Attio export before the production build is sized. Confirm the current minimum requirements in the guide itself, since the project ships frequent releases and the requirements may change.
The operating skills matter as much as the hardware. Twenty is a TypeScript application with a React frontend, backed by NestJS, BullMQ, PostgreSQL and Redis. A team that already runs Node.js services, PostgreSQL backups and Redis monitoring can own the instance with little new learning. A team that runs mostly Windows servers or hosted SaaS tools should decide, before the cutover date, who will patch the containers, rotate database credentials, back up PostgreSQL, watch the worker queue and apply each new release. Write that owner down. If no internal owner exists, ask an implementation partner to quote upgrades and monitoring as a retainer, and confirm in writing who responds when the worker stops during an import.
Check the license with your legal team before you build on it. Twenty's LICENSE file states that the core is AGPL-3.0 with an additional application exception, that files carrying an Enterprise license header fall under a commercial license, and that SDK and UI packages are MIT. Ask counsel whether the planned use, including any internal modifications, customer-facing portals or integrations you build on the APIs, triggers source-sharing obligations, and whether any Enterprise-licensed features are part of the plan. The Twenty LICENSE file on GitHub is the primary text to give counsel. Record their conclusion in the migration plan so the decision is documented before the cutover.
How the migration differs by team size and starting point
A small team with a handful of objects, a default people and companies model, and a short list of automations usually has the lightest migration. The data volume is modest, the relations are few, and the export can be done view by view in an afternoon of checking. Most of the effort goes into confirming that views and fields line up with what the team actually uses day to day.
- Export: Export each list view to CSV or Excel and keep a dated copy of every file, since the set is small enough to verify by hand.
- Recreate: Rebuild the few custom fields and the pipeline stages in Twenty, which lets you test the model before loading real records.
- Import: Load a small sample first, check record counts and relations, then import the full set.
- Automations: Rebuild a short list of workflows in Twenty's workflow feature and test each one with a dummy record.
- Internal work: A team with someone comfortable with a Docker Compose host can usually run the self-hosted stack and these steps internally.
Before you start, confirm with the Twenty self-hosting guide which server, worker, PostgreSQL and Redis resources your host needs, and check which Attio data sits outside list exports.
A team with many custom objects and relations has the largest modeling effort. Each object, field type and relation has to be recreated in Twenty before records can be loaded, and the order of import matters because related records must exist before the links between them can be restored. The work is mostly design and verification, not file handling.
- Model map: Document every object, attribute, relation and cardinality in a spreadsheet before creating anything in Twenty.
- Load order: Import parent records first, then the records that reference them, and keep the record identifiers from the export so links can be rebuilt.
- Relations: Check that many-to-many and multi-select relations come across as intended, since these are the most likely to need manual rework.
- Permissions: Recreate role-based access for each object, because access rules do not travel with an export.
- Ownership: This work benefits from a person who knows both the Attio data model and Twenty's custom objects and fields as code. Ask a partner to review the model map if no one on the team has done this before.
Ask for a written test plan that compares record counts and relation counts per object before anyone switches the team over.
A team that depends on enriched fields, sequences driven by email, and calendar-linked activity has the hardest starting point to reproduce. Attio's enrichment data and email-driven workflows are the parts most likely to export blank or to need a different source in the new setup. Plan these as separate workstreams, not as part of the data export.
- Enriched fields: Treat enriched values as data you must re-source. Decide which enrichment provider, if any, will fill these fields in the new system, and confirm with that provider how it can be connected to a self-hosted CRM.
- Email and calendar sync: Twenty supports email and calendar sync, so test it with a few mailboxes and check how historical threads are handled before relying on it.
- Workflow rebuild: Map each email-triggered workflow to a Twenty workflow step, and test every branch with real but non-sensitive data.
- Activity history: Decide how much past activity you need in the new system and whether an archive is enough.
- Outside help: Integrations and enrichment connections are where a fixed-scope implementation partner most often saves time, so ask for the scope of that work in writing.
Before committing, confirm exactly which fields and activity types Attio's own export includes and which ones you must rebuild by hand.
What drives the cost and duration of the move
How does the number of objects and relations affect the move time?
The number of objects and relations is usually the first driver of effort, because each custom object and each relation has to be recreated in Twenty before any record can be imported. A workspace with a handful of objects and a few links between them is a small modelling task. A workspace where people, companies, deals, projects and partner records point at each other through several relation fields needs a written data model first, with every field type and cardinality agreed. To reduce effort, inventory every object and relation in Attio, remove unused fields, and map each one to a Twenty equivalent on paper before anyone builds anything.
Why do record volume and attachments change the import plan?
Record volume and attachments change how long imports run and how much you must verify afterward. Thousands of records can be loaded in batches with a script against Twenty's API, but attachments are separate files that must be exported and re-linked, and they add storage to the server you run. Plan for a trial import on a copy of a representative slice, measure how long it takes, and check counts and relations against the source. Ask your implementation partner, if you use one, to state how imports, reconciliation and attachment handling are priced.
How do the number of list views and automations change the rebuild?
Each list view and automation is rebuilt by hand, so a long list of them is often the biggest share of internal time. List views are configuration, but they encode filters, sort orders and column choices that people rely on daily. Automations depend on triggers and actions that must be re-expressed in Twenty's workflow tooling. Reduce the work by retiring views nobody opens, consolidating near-duplicates, and documenting each automation's purpose before rebuilding it, so you do not copy logic that no longer serves a process.
Do enrichment dependencies add cost to leaving Attio?
Yes, enrichment dependencies add cost because enriched fields often export blank and must be sourced again. If your team relied on data providers inside Attio, you need a replacement source or a decision to drop those fields, and each provider has its own contract and fees. Confirm with your data providers what you are allowed to export and store before you leave, and budget time to re-enrich only the records that matter. Your Attio export guide covers what stays behind.
Which integrations must be rebuilt, and how do they affect timing?
Every integration that reads or writes CRM data must be rebuilt against Twenty's GraphQL and REST APIs and its webhooks, so the integration count sets the schedule. Typical examples include email and calendar sync, marketing tools, support desks, data warehouses and internal apps. Create a list of every connected tool, the direction of data flow, and the owner of each connection. Test each one against a staging instance before cutover, because an integration that silently stops syncing is hard to spot after go-live.
Who owns hosting and upgrades after the move, and what does that cost?
Your organization owns hosting and upgrades once Twenty runs in your infrastructure, and that is a recurring cost. Twenty's self-hosting guide runs a server, a worker, PostgreSQL and Redis, and asks for at least 2 GB of RAM because insufficient memory can crash processes. Frequent releases, such as v2.48.0 on October 16, 2026, mean someone must test and apply upgrades, back up PostgreSQL, and monitor the worker queue. Decide who holds that role before you start, and price it as an ongoing operations task, not a one-time project.
How much training does the team need, and what should a quote include?
Training is driven by how many people change tools and how different Twenty's workflows are from what they know in Attio. Plan short sessions for administrators on the data model and permissions, and separate sessions for users on views, pipelines and automations. The internal time spent learning is part of the real cost, even when no external fee exists. When you request a written quote, ask for a fixed scope that lists the objects and relations covered, the integrations rebuilt, the import method, the test and cutover steps, handover documentation, and what is excluded, including any upgrade or support retainer.
What usually goes wrong and how to prevent it
Most failed CRM moves are not caused by the software but by data that looked complete and was not, or by two systems running in parallel without owners. The cards below cover the risks that tend to surface after go-live or after the Attio subscription ends, each with a check to run before you cut over.
Blank enriched fields
Enriched attributes such as company data or contact details pulled in by a third-party service may export as empty or not at all, so a clean CSV can still hide missing values. Once the Attio subscription ends, those values cannot be re-pulled from Attio. Before you leave, compare a sample of enriched records field by field against the export, record which fields are blank, and decide whether to re-enrich them from the source service or accept the gap in writing.
Relations broken by identifiers
Attio records and Twenty records carry different internal identifiers, so relations such as a person linked to a company will not survive an import unless you map them with a stable external key. Import parent objects first, store the original Attio record ID in a text field, then match relations on that field. Test one linked chain, such as a contact, its company and its open opportunity, before loading the full dataset.
Duplicate records from parallel runs
Running Attio and Twenty side by side means sales staff may create the same contact in both systems, and a later import then doubles it. Set a cutover date, freeze new record creation in Attio for the final import window, and run a duplicate check on email and company domain in Twenty afterward. Assign one owner who can approve merges so duplicates are not resolved differently by each team.
Automations that stop silently
Workflows, sequences and notifications built in Attio do not move with the data, and an automation that depends on a missing field or a renamed object will often fail without an error that anyone sees. List every automation from Attio, rebuild each one in Twenty's workflow automation, and send a test record through it. Confirm that email and calendar sync are connected to the right mailboxes before the old system goes quiet.
Permissions that do not carry over
Attio's sharing settings for lists, views and records do not translate automatically into Twenty's role-based permissions. A user who could see only their own pipeline in Attio may see everything in Twenty by default, or the reverse. Map each team to a role in Twenty before importing, test with one account per role, and confirm that exported data is not visible to users who should not have it.
An untested restore and upgrade path
After go-live, the self-hosted stack needs backups of PostgreSQL and Redis and a tested upgrade process, because Twenty ships frequent releases. Schedule a full restore into a separate environment before the Attio subscription ends, and document who applies upgrades and how a failed upgrade is rolled back. Ask the implementation partner or your own platform team to show the restore working, not just the backup job reporting success.
Questions buyers ask before moving from Attio to Twenty
How long does a move from Attio to Twenty take?
No fixed duration applies to every move, because the length depends on the work in your own workspace. The main drivers are the number of objects and list views to recreate, the record volume to import, how many fields depend on enrichment, how many automations and integrations must be rebuilt, and how many people need training before cutover. A team with a small, well-documented workspace can finish far faster than one with many custom relations and years of automation history. Ask any implementation partner for a written scope that lists each object, view, automation and integration, and set the timeline from that list. Confirm the duration with your own inventory before you commit to a date.
Can our team migrate from Attio to Twenty without outside help?
Often yes, if your team already runs PostgreSQL, Redis and Docker in production. Twenty's Docker Compose self-hosting guide runs a server, a worker, PostgreSQL and Redis, and it asks for at least 2 GB of RAM because insufficient memory can crash processes. The harder parts are usually modeling objects and relations in Twenty, mapping enriched fields, and rebuilding automations that were built in Attio's interface. Teams without spare capacity or with heavy integrations often bring in help for those steps. DeployOpen plans, implements, hardens, backs up and documents self-hosted platforms in your own infrastructure under a written, fixed scope, so you can hand over only the parts you cannot staff. Confirm your skills and capacity before you decide.
What does the migration need from our Attio and IT admins?
Your Attio admins need to confirm who holds export permissions, then export each object and list view while the data is still complete. Your infrastructure admins need to provision the hosting, databases, backups, TLS certificates and access controls for Twenty, and they need to agree on who operates it afterward. Your security or identity team should decide how users sign in and which role-based permissions map to each team. Plan time for these people in the project schedule, because waiting on access requests is a common cause of delay. Ask each admin group to confirm its tasks in writing before the cutover window is set.
Can we keep enriched data when moving from Attio to Twenty?
Plan on the assumption that enriched fields may export blank, and verify that with your own export before you decline a subscription. Enriched values often come from a provider that Attio connects to, so the data may not be included in a standard export. Before leaving, export every view to a file, store that snapshot in a secure location, and check a sample of enriched columns line by line. If the values matter for reporting or outreach, decide whether to re-enrich records in Twenty through a provider you have contracted, or to keep a read-only copy of the enriched data for reference. Confirm with Attio exactly which fields are included in its exports.
How do we run Attio and Twenty in parallel during the move?
Run them in parallel for a short, defined period with one owner for the cutover decision. Start by loading a pilot group into Twenty, comparing record counts and key fields against Attio, and fixing mapping errors. Then choose a cutover date, set Attio to read-only once users switch, and keep a final export as a fallback. Pay attention to email and calendar sync, because connecting the same mailbox to both systems can create duplicate activity or confusing history. Twenty supports email and calendar sync, so decide which system owns each mailbox during the overlap. Confirm the overlap length and rollback steps in your written plan.
What happens to our Attio API integrations and webhooks?
Each integration must be inventoried, remapped and retested, because Twenty's API shapes differ from Attio's. Twenty exposes both GraphQL and REST APIs and supports webhooks, and its pricing page says all plans include them, so the capability exists even though the calls must be rewritten. List every connected tool, including automation services, data pipelines and internal scripts, along with the objects, fields and events each one uses. Then build test records in Twenty and confirm that each integration reads and writes correctly before switching it over. Ask your engineering team to confirm which integrations depend on Attio-specific behavior.
Does Twenty's license allow us to self-host our customer data?
Twenty's core is mostly licensed under AGPL-3.0 with an additional application exception, and the SDK and UI packages are MIT. Files marked with an Enterprise license header fall under a commercial license, so check which files your deployment uses. Self-hosting the open source core lets you keep customer records on your own servers, and Twenty's pricing page says the core can be self-hosted for free. Because AGPL-3.0 has obligations for modified versions that are offered over a network, ask your legal or compliance team to review any custom code you plan to add. Confirm the license terms in the repository's LICENSE file before you finalize your architecture.
How DeployOpen scopes and runs the Attio to Twenty migration
DeployOpen plans and implements self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks, and this migration follows the same path. We agree scope, deliverables and timelines in writing before work starts, then build, test, document and hand over the Twenty environment and the migrated CRM data.
How we scope
- Inventory every Attio object, list view and enriched field that must move, and record which ones export blank.
- Agree in writing which Twenty objects, relations, views and workflows are in the migration and which are retired.
- Confirm hosting, PostgreSQL and Redis sizing, and who holds administrator access before any work begins.
How we build
- Deploy Twenty with Docker Compose inside your environment, with server, worker, PostgreSQL and Redis configured for your network.
- Recreate objects, fields and relations in Twenty, then run test imports and reconcile record counts against the Attio exports.
- Rebuild priority automations and permissions, and test them with sample records before any production cutover.
How we hand over
- Deliver runbooks covering the environment, the import steps, the object model and the rebuilt workflows.
- Document the export checklist, the mapping of Attio fields to Twenty fields, and the list of items left for manual follow-up.
- Walk your administrators through role-based permissions and the backup procedure before the engagement closes.
How we support
- Keep the written scope as the baseline for change requests, so cost and timeline changes are agreed before they are made.
- Offer ongoing support, upgrades and continuous testing for Twenty as a retainer, sized to your release cadence.
- Ask us to confirm the current Twenty release notes and API changes against your integrations before each upgrade.

