CRM migration

Migrate from EspoCRM to Freshsales

Field-level mapping, validation, and rollback between EspoCRM and Freshsales. We move data and schema; workflows are rebuilt natively in Freshsales.

EspoCRM logo

EspoCRM

Source

Freshsales

Destination

Freshsales logo

Compatibility

82%

9 of 11

objects map 1:1 between EspoCRM and Freshsales.

Complexity

BStandard

Timeline

3-5 weeks

Rollback included Accuracy guarantee Field-level validation

Overview

What this migration involves

Moving from EspoCRM to Freshsales is a structural migration that moves data from a self-hosted AGPLv3 platform to a cloud-native SaaS CRM with built-in email, calling, chat, and AI-powered lead scoring. EspoCRM's Entity Manager creates custom entity types that require metadata export before record migration; Freshsales has no equivalent Entity Manager, so custom entity records map to custom fields on standard objects or to Freshsales custom objects pre-created in the destination. EspoCRM's default 200-record API ceiling and multi-enum field cap of 20 options are migration-surface risks we detect during discovery. Self-hosted EspoCRM instances store file attachments on the server filesystem under data/files/, which requires a separate file-transfer step alongside the database export. We do not migrate EspoCRM Workflows, BPM processes, or custom PHP scripts as code; we deliver a written inventory of these for the customer's admin to rebuild in Freshsales.

Field-level fidelity

Every standard and custom field arrives verified.

Schema-aware mapping

AI proposes the map; you confirm before any record moves.

Relationships preserved

Parent–child, lookups, and ownership stay linked.

Full activity history

Calls, emails, meetings — with original timestamps.

Attachments & notes

Documents, uploads, and inline notes move with the record.

Why teams make this switch

Two sides of the same decision

Leaving

EspoCRM logo

EspoCRM

What's pushing teams away

  • Email and SMS follow-up functionality requires third-party integrations and does not work out of the box, frustrating teams expecting a complete CRM experience.
  • Integration ecosystem is narrow compared to HubSpot or Salesforce, with official integrations limited to Google Workspace, Outlook, Zoom, VoIP, and Stripe.
  • Customization depth requires increasing technical knowledge; complex entity relationships and custom PHP/Before-Save scripts become difficult to maintain across upgrades.
  • Performance degrades on large datasets without careful server configuration; teams with hundreds of thousands of records report slow list views and search.

Choosing

Freshsales logo

Freshsales

What's pulling them in

  • Lowest barrier to entry among major CRMs — the free tier supports up to 3 users and includes core CRM functionality before committing to per-seat pricing.
  • Built-in chat, email, and phone reduce reliance on third-party integrations for basic sales communication and contact management.
  • Freddy AI contact scoring and deal insights are included on Pro plans at a lower price than comparable HubSpot tiers.
  • Kanban pipeline views across Contacts, Accounts, and Deals provide visual deal management without requiring custom configuration.
  • Integration with the broader Freshworks ecosystem (Freshdesk, Freshchat, Freshservice) reduces tool sprawl for teams already using Freshworks.

Object mapping

How EspoCRM objects map to Freshsales

Each row shows how a EspoCRM object lands in Freshsales, including any object-level transformations, lookup resolution, or schema-design dependencies.

Typical mapping — final map is confirmed during the sample migration step.

EspoCRM

Contact

maps to

Freshsales

Contact

1:1
Fully supported

EspoCRM Contact records map directly to Freshsales Contact. We map name, email, phone, address, and any custom fields 1:1. Multi-email fields in EspoCRM (where a contact can have multiple email addresses) are handled by mapping the primary email to the standard email field and storing additional emails in a Freshsales custom multi-value text field that the customer's admin configures before import. If the source EspoCRM instance uses multi-enum fields with more than 20 options, we flag these during discovery and either split into multiple picklist fields or store as a comma-separated text field.

EspoCRM

Account

maps to

Freshsales

Account

1:1
Fully supported

EspoCRM Account records map to Freshsales Account with company name, website, industry, billing address, and phone preserved. Account is created before Contact import so that the Contact-to-Account relationship is satisfied at insert time. EspoCRM link-multiple relationships from Account to Contact are reconstructed as Freshsales Account-Contact lookups using ID remapping tables.

EspoCRM

Lead

maps to

Freshsales

Lead

1:1
Fully supported

EspoCRM Lead records with conversion status map to Freshsales Lead. The EspoCRM lead_status field maps to Freshsales Lead Status. Any lead_score or rating values stored as custom fields migrate to Freshsales custom fields. Leads that were converted in EspoCRM (with linked Account and Contact created) are imported as Freshsales Leads with a note flagging their converted status; the customer decides whether to convert them again in Freshsales or treat them as closed leads.

EspoCRM

Opportunity

maps to

Freshsales

Deal

1:1
Fully supported

EspoCRM Opportunity records map to Freshsales Deal. Opportunity amount, stage, probability, and expected close date transfer to Freshsales Deal amount, stage, probability, and expected close date. EspoCRM stage values are mapped to Freshsales pipeline stage names during discovery. The Opportunity-to-Account link is resolved via the Account ID remapping table at migration time.

EspoCRM

Case

maps to

Freshsales

Case

1:1
Fully supported

EspoCRM Case records (support tickets) map to Freshsales Case. Case status, priority, resolution fields, and the full conversation thread (stored as Activity or Note records in EspoCRM) migrate to Freshsales Case with the same relationships. The EspoCRM case number becomes a custom field on Freshsales Case to preserve audit traceability.

EspoCRM

Campaign

maps to

Freshsales

Campaign

1:1
Fully supported

EspoCRM Campaign records migrate to Freshsales Campaign. Campaign targeting lists (linked Leads and Contacts) are recreated as Freshsales Campaign Members after the Lead and Contact imports complete. We note that EspoCRM email send history (open rates, click data) does not migrate because this is a live-metrics feature; only the campaign record and targeting list transfer.

EspoCRM

Custom Entity (Entity Manager)

maps to

Freshsales

Custom Field or Custom Object

lossy
Fully supported

EspoCRM custom entity types created via Entity Manager require metadata export before record migration. We export the entityDefs metadata to identify all custom fields, field types, and relationships. For simple custom entities with a 1:many relationship to a standard object (e.g., a Project entity linked to Account), we create Freshsales custom fields on the parent object and store the custom entity data as serialized JSON in a long-text field or split into individual custom fields based on data type. For complex custom entities with cross-references to other custom entities, we pre-create Freshsales custom objects, define lookup relationships, and migrate in dependency order using topological sort.

EspoCRM

Activities (Meetings, Calls, Tasks)

maps to

Freshsales

Activities

1:1
Fully supported

EspoCRM Activities (Meetings, Calls, Tasks) linked to Contacts, Accounts, or Opportunities migrate to Freshsales Activities on the corresponding record. We resolve the parent record via ID remapping tables and preserve the original activity timestamp for timeline ordering. Meeting attendees are stored as Freshsales Activity participants linked via the activity ID.

EspoCRM

Email (stream records)

maps to

Freshsales

Email

1:1
Fully supported

EspoCRM stream records of type Email migrate to Freshsales Email records linked to the sender and recipient Contact or Lead. Email body content transfers as HTML. The EspoCRM Stream (activity feed) is a live-data feature and is not reproduced in Freshsales; only the email record itself migrates.

EspoCRM

Attachment (filesystem)

maps to

Freshsales

Attachment (cloud storage)

lossy
Fully supported

On self-hosted EspoCRM instances, uploaded files live on the server filesystem under data/files/ and are not stored as database blobs. A standard database export will not capture these files. We identify Attachment records during discovery, extract the referenced files from the filesystem archive, transfer them alongside the record migration, and re-register each file with the corresponding Freshsales object record. We validate that Freshsales file storage limits on the destination plan accommodate the total attachment volume before migration begins.

EspoCRM

User

maps to

Freshsales

User

1:1
Fully supported

EspoCRM User records map to Freshsales User by email match. We extract user name, email, role assignment, and team memberships from EspoCRM. EspoCRM role permissions have no direct Freshsales equivalent, so we deliver a role mapping table for the customer's admin to configure Freshsales roles, territories, and visibility groups post-migration. Unmatched EspoCRM users go to a reconciliation queue.

Gotchas + challenges

What specifically takes care here

Platform-specific issues from each side, plus the pair-specific challenges that don't show up on either platform's page on its own.

EspoCRM logo

EspoCRM gotchas

Medium

Default 200-record API GET ceiling requires pagination

High

Server migration leaves WebSocket references pointing to old domain

Medium

Multi-enum field option cap of 20 limits data fidelity

High

Custom entity import ordering creates chicken-and-egg reference problems

Medium

Attachments on self-hosted instances are filesystem-stored

Freshsales logo

Freshsales gotchas

Medium

Freddy AI is Pro-tier only despite heavy marketing

High

Post-migration emails and sequences are disabled

Medium

Bot session credits are a one-time 500-session allocation

Medium

Phone credits charged per minute with no cap

Low

File storage limits scale with plan tier

Pair-specific challenges

  • Multi-enum fields capped at 20 options cause import validation failures

    EspoCRM multi-enum fields are capped at 20 selectable options by default. If your source entity uses a multi-enum field with 15 or more options and the destination Freshsales custom field is a standard picklist, records may fail Freshsales validation during import. We detect all multi-enum fields during discovery, count their options, and advise whether to migrate as a Freshsales multi-select picklist (limited to 500 options, well above 20), split into multiple fields, or store as a comma-separated text field. This must be resolved before any record import begins.

  • Custom entity cross-references create chicken-and-egg import ordering problems

    EspoCRM Entity Manager custom entity types can reference each other via link-multiple or foreign-key relationships. If you import records in the wrong order, child records with missing parent references fail EspoCRM's referential integrity on save. Freshsales enforces lookup requiredness similarly. We perform a dependency graph analysis of all Entity Manager entity types before migration, topologically sort the import order, and use ID remapping tables so that forward references resolve correctly when source IDs differ from Freshsales IDs. This step is the most common source of silent data loss in EspoCRM-to-any-destination migrations.

  • Self-hosted filesystem attachments require separate file-transfer step

    On self-hosted EspoCRM instances, uploaded files are stored on the server filesystem under the data/files/ directory rather than as blob records in the database. A standard database export and restore will not capture these files. If your migration scope includes Document or Attachment records, we identify the referenced files during discovery, extract them from the filesystem archive, transfer them alongside the record migration, and re-register each file with the corresponding Freshsales object record. We validate that Freshsales storage limits on the destination plan accommodate the total attachment volume before migration begins.

  • EspoCRM API 200-record ceiling requires paginated extraction

    The EspoCRM REST API returns a maximum of 200 records per GET request by default, controlled by the maxSize parameter. Migrating large datasets requires chunked, paginated extraction loops. We detect the total record count from the first response header and orchestrate sequential page fetches to pull all records without silent truncation. For migrations exceeding 50,000 records on a single entity type, we also configure maxSize explicitly during migration to balance throughput against source server load.

  • Freshsales Lead-to-Contact conversion is a separate action, not automatic

    Freshsales treats Leads and Contacts as distinct record types. Unlike EspoCRM, where a Lead can be linked to an Account without an explicit Convert action, Freshsales requires a formal Lead Conversion step to generate a Contact and Account from a Lead. We import EspoCRM Leads as Freshsales Leads (not as Contacts) and flag any EspoCRM Leads that were already converted, so the customer's admin can decide whether to convert them again or treat them as closed won. This preserves the EspoCRM behavior where Leads live independently until explicitly linked.

Migration approach

Six steps for a successful EspoCRM to Freshsales data migration

  1. Discovery and entity audit

    We audit the source EspoCRM instance across all entity types including Entity Manager custom entities, custom fields, multi-enum field option counts, attachment records, and cross-entity relationship types. We extract the entityDefs metadata for all custom entities and inventory the data/files/ directory for filesystem-stored attachments. We also identify the EspoCRM API endpoint structure, confirm whether the instance is cloud or self-hosted, and assess record volumes per entity type. The discovery output is a written migration scope with entity counts, custom field inventory, multi-enum flag report, and attachment volume estimate.

  2. Destination schema preparation in Freshsales

    We create Freshsales custom fields to match EspoCRM custom fields that do not have direct Freshsales equivalents, configure picklist values (checking Freshsales's 500-option limit against the source multi-enum counts), and pre-create any Freshsales custom objects needed for complex Entity Manager entity types. We configure pipeline stages in Freshsales to match EspoCRM Opportunity stages. All schema changes are applied to the destination Freshsales account before any record migration begins. We coordinate with the customer's Freshsales admin to apply any role and visibility configurations.

  3. Dependency graph analysis and import ordering

    We analyze all EspoCRM entity types and their cross-references to construct a dependency graph. Topological sorting of this graph determines the safe import order (e.g., Accounts before Contacts, Contacts before Activities). We build ID remapping tables so that when source EspoCRM IDs appear as foreign keys in related records, they map correctly to the Freshsales IDs assigned during import. This step resolves the chicken-and-egg ordering problem that causes orphaned relationships in automated migration tools.

  4. Filesystem attachment extraction and staging

    For self-hosted EspoCRM instances, we identify all Attachment records during discovery, map each attachment record to its filesystem path under data/files/, and extract the files to a staging directory. We validate that each extracted file's MIME type is supported by Freshsales attachment upload. We estimate total attachment volume and confirm it fits within the destination Freshsales plan's storage limits before proceeding to import.

  5. Production migration in dependency order

    We run production migration in record-dependency order: Accounts, then Leads, then Contacts, then Opportunities, then Cases, then Campaigns, then Activities and Emails, then Custom Entities, then Attachments last. Each phase emits a row-count reconciliation report before the next phase begins. ID remapping tables are updated after each phase so that subsequent phases resolve parent lookups correctly. We use the Freshsales Bulk Import API for large record sets and the REST API for smaller entities and attachments.

  6. Cutover, validation, and Workflow inventory handoff

    We freeze EspoCRM writes during cutover, run a final delta migration of any records modified during the migration window, then enable Freshsales as the system of record. We deliver a written inventory of all EspoCRM Workflows, BPM processes, and custom PHP/Before-Save scripts requiring rebuild in Freshsales. We support a one-week hypercare window where we resolve reconciliation issues raised by the customer's team. We do not rebuild EspoCRM automations as Freshsales workflows inside the migration scope; that is a separate engagement.

Platform deep dives

Context on both ends of the pair

EspoCRM logo

EspoCRM

Source

Strengths

  • AGPLv3 open-source license with no per-contact or per-seat recurring fee on self-hosted deployments.
  • Entity Manager provides a UI for creating custom entity types, fields, and relationships without writing code.
  • Full REST API covers all standard CRUD operations plus stream, metadata, and currency rate endpoints.
  • Cloud plans include daily backups with 7-day retention and all official extensions at no additional cost.
  • Both cloud-hosted and fully self-hosted deployment options with explicit customer data ownership.

Weaknesses

  • Email and SMS functionality requires third-party integrations and does not work natively out of the box.
  • Official integrations are limited to Google Workspace, Outlook, Zoom, VoIP, and Stripe.
  • Multi-enum field type is capped at 20 options by default and requires configuration changes to extend.
  • Large record volumes without server-side performance tuning cause slow list views and degraded search performance.
  • WebSocket domain references can persist after server migration if internal URL configuration is not fully updated.
Freshsales logo

Freshsales

Destination

Strengths

  • Generous free tier for small teams with core CRM functionality without per-seat costs.
  • All-in-one sales CRM with built-in telephony, chat, and email reducing third-party tool dependency.
  • Freddy AI contact scoring and deal predictions available on Pro tier.
  • Multiple pipeline views with Kanban and list options across all plans.

Weaknesses

  • Reports lack depth compared to competitors like HubSpot, with limited customization options.
  • Integration setup is poorly documented with no clear guides for connecting third-party tools.
  • AI features gated behind $39/user/month Pro tier despite marketing emphasis on Freddy AI.
  • Bot sessions limited to 500 one-time allocation with no monthly refresh.

Complexity grading

How hard is this migration?

Standard CRM migration. 2 of 8 objects need a mapping; the rest are 1:1.

B

Overall complexity

Standard migration

Derived from compatibility, mapping clarity, API constraints, and data volume across EspoCRM and Freshsales.

  • Object compatibility

    B

    2 of 8 objects need a mapping; the rest are 1:1.

  • Field mapping clarity

    C

    Field mapping is derived from defaults — final spec confirmed during the sample migration.

  • Timeline complexity

    B

    8-object category — typical timelines run 2–7 days end-to-end.

  • API constraints

    B

    EspoCRM: Not publicly documented; rate limits can be configured server-side in the EspoCRM config file.

  • Data volume sensitivity

    B

    EspoCRM doesn't expose a bulk API — REST + parallelization used for high-volume runs.

Estimator

Estimate your EspoCRM to Freshsales migration cost

Rule-based pricing — no per-record fees, no manual quotes. Migrations over 2M records are scoped individually.

Step 1

What are you migrating?

Pick a category, then your source and destination platforms.

Category

FAQ

Frequently asked questions about EspoCRM to Freshsales data migrations

Answers to the questions buyers ask most during EspoCRM to Freshsales migration scoping. Not seeing yours? Book a call.

Can't find your answer?

Walk through your EspoCRM to Freshsales migration with a real engineer — 30 minutes, free, written quote within 24 hours.

Book a free 30 minute consultation

Most migrations land between three and five weeks for accounts under 10,000 Contacts and 2,000 Opportunities with no custom Entity Manager entities. Migrations with Entity Manager custom entity types, multi-enum fields approaching the 20-option cap, large attachment directories, or complex cross-entity relationships move to eight to twelve weeks because of metadata extraction, file transfer, field-type transformation, and dependency-resolution work. Timeline assumes the customer's Freshsales admin is available within two business days for schema approvals and user provisioning.

Adjacent paths

Related migrations to explore

Ready when you are

Move from EspoCRM.
Land in Freshsales, intact.

Tell us record counts and timeline. We'll come back with a written quote inside 1 business day — no commitment, no sales pitch.

Accuracy guarantee Rollback included Quote in 1 business day