Remove metadata fast β€” MetaRemover.com

Custom Metadata in Salesforce (2025)

Model configuration as metadata you can version, test, and deploy. Learn differences vs Custom Settings, how to create types & records, and how to ship them with the Metadata API and sf CLI.

Custom Metadatapackage.xmlCI/CD2025

Deployability

Move config across orgs

Across environmentsExcellent

Governance

Version control friendly

VCS fitHigh

Performance

Low runtime overhead

Read latencyLow

Overview: why Custom Metadata

Custom Metadata lets you convert hard-coded logic into deployable configuration. Instead of toggles in code or per-org data, you define a Custom Metadata Type with fields and ship records as metadata. This enables peer reviews, version control, automated tests, and repeatable releases.

Key idea
Store non-secret configuration that governs behavior across environments. Reference via SOQL in Apex, Flow, or formula functions where supported.

Custom Metadata vs Custom Settings

AspectCustom MetadataCustom Settings
DeployabilityDeployable across orgs (metadata)Org data (not deployable)
Version controlExcellent (source files)Limited
Use casesFeature flags, routing, limits, mappingsOrg/runtime specific settings
SecurityAvoid secrets/PIIAvoid secrets/PII
Working with images in Knowledge/Experience Cloud? Before attaching, quickly scrub hidden EXIF/GPS using a privacy-first, browser-only cleaner β€” MetaRemover.com. No uploads, just local processing.

Create Custom Metadata Types & Records

Setup β†’ Custom Metadata Types

Point-and-click creation

  1. Create a Custom Metadata Type (label, object name, visibility).
  2. Add custom fields (e.g., Text, Checkbox, Number) for your config.
  3. Click Manage Records β†’ create records (per environment or global).
  4. Reference from Apex/Flow using SOQL or metadata relationship fields.
Tip
Avoid environment-specific values when possible. If needed, encode environment in a field or use branching records.

package.xml examples

Include CustomMetadata (records) and CustomObject (the type definition) along with any fields or validation rules your type uses.

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
  <types>
    <members>FeatureFlag__mdt.Flag_EnableRouting</members>
    <members>FeatureFlag__mdt.Flag_UseNewUI</members>
    <name>CustomMetadata</name>
  </types>
  <types>
    <members>FeatureFlag__mdt</members>
    <name>CustomObject</name>
  </types>
  <version>59.0</version>
</Package>
Best practice: model modules separately (flags, routing, limits) to keep diffs small and deployments predictable.

Retrieve & deploy with sf CLI

Retrieve (manifest)

MDAPI β†’ convert to source

sf project retrieve start --manifest manifest/package.xml --target-org MySandbox --output-dir mdapi_outsf project convert mdapi --root-dir mdapi_out --output-dir force-app

Deploy (validate then resume)

Fast & safe

sf project deploy start --manifest manifest/package.xml --target-org UAT --dry-run --test-level RunLocalTestssf project deploy resume --use-most-recent --target-org UAT
Tip
Keep test levels consistent with org policy. Use validation to shorten production windows.

Pre-deploy checklist

  • Version bump for your module documented
  • Records reviewed for environment-specific values
  • Profiles/PermissionSets unaffected or updated
  • Validation-only run green (save the deployment ID)

CI/CD workflows

GitHub Actions snippet

JWT auth + validate + deploy

name: deploy-custom-metadata
on:
  push:
    branches: [ "release/*" ]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: salesforcecli/action@v1
      - name: Auth JWT
        run: |
          sf org login jwt --client-id $SF_CONSUMER_KEY \
            --jwt-key-file server.key \
            --username $SF_USERNAME --alias CI_UAT
      - name: Validate
        run: |
          sf project deploy start --manifest manifest/package.xml \
            --target-org CI_UAT --test-level RunLocalTests --dry-run
      - name: Resume deploy
        if: success()
        run: |
          sf project deploy resume --use-most-recent --target-org CI_UAT

Common pitfalls

Save hours during releases

  • Forgetting the CustomObject entry for the __mdt type
  • Environment-specific records accidentally promoted to prod
  • Secrets or PII stored in metadata (avoid)
  • API version mismatch in package.xml
Tip
Use small, focused manifests per module. Keep a β€œcanary” package to quickly validate pipeline health.

Images in org content: quick privacy tip

If your team publishes images (Knowledge, Experience Cloud, Email), scrub hidden EXIF/GPS and authoring traces before upload. It’s a simple step that prevents accidental location or device leaks in public assets.

Try a privacy-first, browser-only cleaner β€” MetaRemover.com. Processes files locally, no server uploads.

FAQ

Before you attach images to Salesforce content, sanitize metadata with a browser-only tool like MetaRemover.com. Quick, private, no uploads.

Ship configuration with confidence

Keep your config as deployable metadata, validate first, and automate. One more thing: keep public images clean of hidden data.