Metadata API deploys and retrieves customizations in bulk, as a zip of files, with rollbackOnError available so a failed deployment does not leave the org half changed. Tooling API reaches into the same metadata one element at a time, and queries much of it with SOQL.
The rule that decides almost every case: if a person is waiting for the answer, use Tooling API. If a pipeline is moving a release, use Metadata API. Salesforce puts it plainly, saying that smaller retrieves improve performance, which makes Tooling API a better fit for developing interactive applications.
Side by side
| Metadata API | Tooling API | |
|---|---|---|
| Unit of work | A zip of files | A single element |
| Can query with SOQL | No | Yes, for many metadata types |
| Change one field on a complex type | Retrieve, edit, redeploy the whole thing | Change just that element |
| Concurrency | One deployment at a time, the rest queue | Concurrent requests |
| Built for | Release automation and packaging | Developer tools and interactive apps |
| Typical caller | A CI pipeline | An IDE, an extension, an admin tool |
Salesforce states that because Tooling API lets you change just one element within a complex type, it can be easier to use than Metadata API. That is the practical difference. Changing one picklist value through Metadata API means retrieving the object, editing the file and deploying it back. Through Tooling API it is one call.
Metadata API limits worth knowing before you plan a release
| Limit | Value |
|---|---|
| Max files, unlocked or second-generation package | 10,000 |
| Max files, first-generation managed package | 35,000, and only for 1GP packages that have passed the AppExchange security review |
| Max compressed zip size | Approximately 39 MB |
| Max uncompressed folder size | Approximately 600 MB |
| Deployment status retention | 30 days |
| Concurrent deployments | One at a time, others queue |
Two of these surprise people.
The 39 MB compressed cap is not arbitrary. Base64 encoding inflates the payload by roughly 22%, so a 39 MB zip arrives near the 50 MB post-encoded ceiling. Sizing against 39 MB rather than 50 MB is the difference between a deployment that works and one that fails at upload with an unhelpful message.
One deployment at a time. You can initiate several, but only one runs, and the rest wait in a queue. Any pipeline that fans out parallel deploys to the same org is not going faster, it is queueing, and the timeouts it eventually hits will look like a platform problem rather than a design one.
The 35,000 file allowance is conditional. It applies to first-generation managed packages that have passed the AppExchange security review. Unlocked and second-generation packages cap at 10,000. If you are planning a 2GP package around a large codebase, 10,000 is the number to design against.
What Tooling API is actually for
The documented tasks are broader than most people expect:
- Retrieving metadata about object fields and object properties
- Managing working copies of Apex classes, triggers, Visualforce pages and components
- Checking for updates and errors in code
- Setting heap dump markers and overlaying Apex or SOQL statements
- Executing anonymous Apex
- Generating and accessing debug logs
- Accessing code coverage results
- Running tests and managing test results
- Managing validation rules and workflow rules
- Supporting source control integration and continuous integration
The debugging entries are the ones teams miss. Heap dump markers, checkpoint overlays and code coverage results are all Tooling API surfaces, which is why a custom quality dashboard is a Tooling API project rather than a Metadata API one.
Saving Apex without a deployment
Compiling Apex through Tooling API uses three objects together: MetadataContainer, ApexClassMember and ContainerAsyncRequest. You create a container, add a member holding the new body, submit an async request, and poll for the compile result.
It is more moving parts than a deployment, and it is how every Salesforce IDE saves a class in under a second. Reach for it when you are building a tool. Do not reach for it to ship a release.
Choosing between them
Use Metadata API for release pipelines, packaging, org-to-org migrations, retrieving a full metadata snapshot, and anything that must succeed or fail as a unit.
Use Tooling API for editors and extensions, admin tools that change one thing, querying what exists without pulling a zip, code coverage and test result reporting, and anything a person is waiting on.
Use both in any serious tooling build. Tooling API for the interactive surface, Metadata API for the deployment that follows.
One practical note for packaging teams: neither API is how you cut a package version. That is the Salesforce CLI and 2GP packaging commands, with Metadata API underneath as the transport for the source. Our guide to creating a managed package covers that path.
Frequently Asked Questions
What is the difference between Metadata API and Tooling API?
Metadata API retrieves and deploys customizations in bulk as a zip of files, and is built for release automation. Tooling API provides fine-grained access to individual metadata elements and supports SOQL queries against many metadata types, which makes it the right choice for interactive developer tools.
Can I query metadata with SOQL?
Through Tooling API, yes, for many metadata types. Metadata API has no SOQL interface, so discovering what exists in an org means retrieving it. Querying through Tooling API is dramatically faster when you only need to know whether something is there.
What is the maximum Metadata API deployment size?
Approximately 39 MB compressed and approximately 600 MB uncompressed. The compressed figure accounts for base64 encoding adding roughly 22% in transit, keeping the encoded payload under 50 MB.
How many files can a Salesforce package contain?
10,000 for unlocked and second-generation managed packages. 35,000 for first-generation managed packages, and only where the 1GP package has passed the AppExchange security review.
Can Salesforce run multiple deployments at once?
No. You can initiate multiple deployments, but only one runs at a time and the others queue until it finishes. Parallel deploys to a single org add queue time rather than reducing it.
How do I save an Apex class without deploying?
Through Tooling API, using MetadataContainer, ApexClassMember and ContainerAsyncRequest together: create the container, add a member with the new body, submit an async request, then poll for the compile result. This is how Salesforce IDEs save a class in near real time.
How long is Metadata API deployment status available?
30 days. Deployment status can be checked while a deployment runs and for deployments completed in the last 30 days, so any audit trail you need beyond that has to be captured by your own pipeline.
Related Articles
- How to create a managed package in Salesforce
- 1GP to 2GP managed package migration
- Salesforce Code Analyzer guide
- Salesforce integration patterns and best practices
Sources
- Salesforce Developers, Metadata API Developer Guide, Deploying and Retrieving Metadata: file counts by package type, compressed and uncompressed size caps, base64 overhead, 30 day status retention, single concurrent deployment. 2/ Salesforce Developers, Tooling API Developer Guide, When to Use Tooling API and Introducing Tooling API: documented task list, SOQL retrieval comparison, MetadataContainer, ApexClassMember and ContainerAsyncRequest. Verified 2 September 2026.



