Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram illustrating the structure and usage of Salesforce audit fields during data migration planning.
Admin

Understanding Salesforce audit fields for data migration

Ever wonder why you can't edit a record's creation date? Those are Salesforce audit fields. They are locked by default, but a data migration is the one time you need them open, and here is how to do that without wrecking your data.

The short answer

Salesforce audit fields record who created and last modified a record and when. They are read-only by default for compliance reasons. Administrators can turn on an org setting and grant a permission set so these fields can be populated through the API during a data migration.

Key takeaways Turn on Set Audit Fields upon Record Creation in User Management Settings, then grant the permission to your migration user through a permission set. Turn on Update Records with Inactive Owners so you can set CreatedById to an inactive user without hitting an error. Map audit fields only on the initial insert. Salesforce will not let you update them on records that already exist. Test date formats and time zones in a sandbox with a small batch before you load anything into production.

Ever wondered why you can't just change a record's creation date? Those system-managed timestamps are the Salesforce audit fields, and they tell you who touched a record and when. If you have ever done a data migration, you know how frustrating it is when your legacy data suddenly looks like it was all created "today" by "Admin User."

What exactly are Salesforce audit fields?

These fields record the "who" and the "when" for every insert and update. By default they are strictly read-only, because Salesforce relies on them for data integrity and compliance. You will see them on almost every object, and they usually include:

  • CreatedById: the user who first hit save.
  • CreatedDate: the exact moment the record was born.
  • LastModifiedById: the person who last tweaked the data.
  • LastModifiedDate: when that last change happened.
  • SystemModstamp: this one is purely for the system, used for things like search indexing and replication.

You can see these fields in a report or on a page layout, but you can't touch them through a standard edit. So what happens when you're moving five years of history from an old SQL database into a fresh org? You don't want every record to show today's date.

How to enable Salesforce audit fields for migrations

If you're planning a big move, you'll need to bypass the standard read-only rules. In the past, you had to open a support case and practically beg for permission. Thankfully, Salesforce made it easier. You can now enable a setting called "Set Audit Fields upon Record Creation" directly in your User Management Settings.

Once you flip that switch, you can assign the "Set Audit Fields" permission to your migration user via a permission set. But don't leave this on for everyone. I've seen teams leave it enabled for regular users, and it's a recipe for data chaos. Keep it locked down to your service account or migration lead.

The catch with inactive owners

One thing that trips people up during migrations is trying to map records to users who no longer work at the company. If you try to set a CreatedById to an inactive user, the system will throw an error. You'll need to enable another setting called "Update Records with Inactive Owners" to make this work. I've written a more detailed guide on assigning records to inactive users if you're stuck on that specific hurdle.

Practical tips for your data migration

When you're ready to start pushing data, you'll need to use the API. Data Loader, Workbench and the Bulk API all do the job. A REST payload that sets audit fields looks like this:


POST /services/data/v60.0/sobjects/Account/
{
  "Name": "Legacy Client Corp",
  "CreatedDate": "2018-05-20T09:00:00.000Z",
  "CreatedById": "005XXXXXXXXXXXXXXX"
}

There is a limit to what you can do, though. Even with the special permissions, you can't update these fields on existing records. This only works during the initial insert. If you've already loaded 50,000 records and forgot to set the dates, you're looking at a delete-and-reload scenario. Trust me, I've been there, and it isn't fun.

Pro Tip: Always run a small test batch of 10 records in a sandbox first. Check the timestamps in a SOQL query to make sure the time zones didn't get mangled during the CSV export.

Best practices for data integrity

If you're in a regulated industry like finance or healthcare, your auditors will care deeply about these dates. If you're also dealing with heavy automation, it's worth checking how Salesforce Flow handles data integrity so your migration doesn't trigger a pile of unwanted emails or tasks.

  • Use a dedicated migration user, not your own admin account. It makes it far easier to work out later which records came in with the import.
  • Watch your time zones. Salesforce stores everything in UTC. If your source data is in EST, you'll need to do the math before you upload.
  • Document the "why". If an auditor asks why a record says it was created in 2015 but the org didn't exist until 2024, you'll want a paper trail.

Key takeaways

  • Salesforce audit fields are system-managed and read-only by default, for compliance.
  • You can enable the ability to set these fields for migrations through User Management Settings.
  • You can only set audit fields during record creation, not on updates.
  • Always use a sandbox to test your CSV headers and date formats before hitting production.

Audit fields exist to protect the truth of your data. Use the "Set Audit Fields" feature when a migration genuinely needs it, but treat it like a power tool: use it carefully and put it away when you're done. If you can't enable it for some reason, your fallback is creating custom "Legacy Created Date" fields, but that usually just clutters up your schema. Do it the right way if you can.

Frequently asked questions

Can you update audit fields on existing records in Salesforce?

No. Audit fields can only be populated during the initial record creation through the API. If existing records need different audit dates, you have to delete them and load them again.

How do you enable Set Audit Fields upon Record Creation in Salesforce?

Turn on the Set Audit Fields upon Record Creation option in User Management Settings in Setup. Then grant the Set Audit Fields permission to your migration user or integration account through a permission set.

How do you set CreatedById to an inactive user in Salesforce?

By default Salesforce throws an error when you assign CreatedById to an inactive user. Turn on the Update Records with Inactive Owners setting so legacy records can be mapped to inactive users.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment